Download Latest Version phpMan.php.gz (34.3 kB)
Email in envelope

Get an email when there's a new version of phpMan

Home
Name Modified Size InfoDownloads / Week
README.md 2026-05-31 18.6 kB
phpMan.php.gz 2026-05-31 34.3 kB
Totals: 2 Items   52.9 kB 0

phpMan — Unix Man Page / Perldoc / Info Page Web Interface & MCP Server

A single-file PHP web interface and Model Context Protocol (MCP) server for Unix man, perldoc, info, and apropos commands.

For AI Agents: Query Unix documentation via MCP protocol or REST API. Get structured man pages with parsed flags, examples, and cross-references.

Quick Start for Agents

Add to your MCP client configuration:

mcpServers:
  phpman:
    url: "https://www.chedong.com/phpMan.php/mcp"

REST API (Fallback)

# Get structured man page as JSON
curl "https://www.chedong.com/phpMan.php/man/ls/1/json"

# Get MCP-wrapped output
curl "https://www.chedong.com/phpMan.php/man/ls/1/mcp"

Project Home

⚠️ SourceForge no longer supports PHP (since 2025-05-20). The dynamic demo runs on chedong.com.

Screenshot

phpMan: perldoc page with TOC sidebar


MCP Server Protocol

phpMan implements the Model Context Protocol (MCP) specification version 2024-11-05 via Streamable HTTP transport.

Endpoint

POST https://www.chedong.com/phpMan.php/mcp
Content-Type: application/json

Available Tools

1. cli_help — Get Command Documentation

Returns structured documentation for any Unix command, Perl module, or GNU info page.

Input Schema:

{
  "command": "string (required) — Command name (e.g. 'ls', 'git', 'File::Basename')",
  "section": "string (optional) — Manual section (e.g. '1', '3pm'). Omit for best-match."
}

Returns:

  • content[0].text — Full JSON response as string (for LLM parsing)
  • structuredContent — Programmatic access to flags, examples, synopsis, and cross-references

Example:

curl -X POST "https://www.chedong.com/phpMan.php/mcp" \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "cli_help",
      "arguments": {"command": "tar", "section": "1"}
    }
  }'

Auto-detection:

  • Commands containing :: or section 3pm/3perlperldoc mode
  • Other commands → man mode

2. cli_search — Search Man Pages

Search across all man page names and descriptions using apropos.

Input Schema:

{
  "query": "string (required) — Search keyword (e.g. 'recursive delete', 'network', 'cron')",
  "section": "string (optional) — Restrict to manual section (e.g. '1', '8')"
}

Returns:

  • content[0].text — JSON with search results
  • structuredContent — Programmatic access to results array

Example:

curl -X POST "https://www.chedong.com/phpMan.php/mcp" \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 2,
    "method": "tools/call",
    "params": {
      "name": "cli_search",
      "arguments": {"query": "cron"}
    }
  }'

MCP Protocol Flow

1. Initialize (handshake):

{"jsonrpc":"2.0", "id":1, "method":"initialize", "params":{"protocolVersion":"2024-11-05"}}

Response includes serverInfo.name = "phpMan", capabilities.tools.listChanged = false

2. List Tools:

{"jsonrpc":"2.0", "id":2, "method":"tools/list"}

Returns the two tools above with their inputSchema

3. Call Tool:

{"jsonrpc":"2.0", "id":3, "method":"tools/call", "params":{"name":"cli_help", "arguments":{...}}}

4. Notifications (optional):

{"jsonrpc":"2.0", "method":"notifications/initialized"}

Server returns HTTP 202 (no-op)

Error Handling

MCP errors follow JSON-RPC 2.0:

{
  "jsonrpc": "2.0",
  "id": 3,
  "error": {
    "code": -32603,
    "message": "Internal error: Unknown tool: nonexistent"
  }
}

Common error codes:

  • -32700 — Parse error (invalid JSON)
  • -32600 — Invalid request (missing method)
  • -32601 — Method not found
  • -32602 — Invalid params
  • -32603 — Internal error (tool execution failed)

JSON Schema Reference

Both MCP structuredContent and REST /json endpoints return the same schema.

Man Page Response

{
  "mode": "man",
  "parameter": "tar",
  "section": "1",
  "url": "https://www.chedong.com/phpMan.php/man/tar/1/json",
  "generated": "2026-01-15T10:30:00Z",

  "synopsis": "tar [OPTION...] [FILE]...",
  "summary": "tar - An archiving utility",

  "sections": {
    "NAME": {
      "content": "tar - An archiving utility",
      "subsections": []
    },
    "SYNOPSIS": {
      "content": "tar [OPTION...] [FILE]...",
      "subsections": []
    },
    "DESCRIPTION": {
      "content": "The GNU tar program...",
      "subsections": []
    },
    "OPTIONS": {
      "content": "",
      "subsections": [
        {
          "name": "-c, --create",
          "content": "Create a new archive",
          "flag": "-c",
          "long": "--create",
          "arg": null
        },
        {
          "name": "-f, --file=ARCHIVE",
          "content": "Use archive file or device ARCHIVE",
          "flag": "-f",
          "long": "--file",
          "arg": "ARCHIVE"
        }
      ]
    },
    "EXAMPLES": {
      "content": "tar -cvf archive.tar file1 file2\ntar -xvf archive.tar",
      "subsections": []
    }
  },

  "flags": [
    {
      "flag": "-c",
      "long": "--create",
      "arg": null,
      "description": "Create a new archive"
    },
    {
      "flag": "-f",
      "long": "--file",
      "arg": "ARCHIVE",
      "description": "Use archive file or device ARCHIVE"
    }
  ],

  "examples": [
    "tar -cvf archive.tar file1 file2",
    "tar -xvf archive.tar"
  ],

  "see_also": [
    {
      "name": "gzip",
      "section": "1",
      "url": "https://www.chedong.com/phpMan.php/man/gzip/1/json"
    }
  ]
}

Field Descriptions

Field Type Description
mode string "man", "perldoc", "info", or "search"
parameter string Command or module name
section string Manual section number (e.g. "1", "3pm")
url string Canonical JSON API URL for this page
generated string ISO 8601 timestamp (UTC)
synopsis string Command synopsis (extracted from SYNOPSIS section)
summary string One-line description (extracted from NAME section)
sections object Map of section names → section objects
sections[name].content string Section body text (newline-separated)
sections[name].subsections array Level-2 headings within section
subsections[].name string Subsection heading (e.g. "-c, --create")
subsections[].content string Subsection body text
subsections[].flag string|null Short flag (e.g. "-c") — only for option subsections
subsections[].long string|null Long flag (e.g. "--create") — only for option subsections
subsections[].arg string|null Argument placeholder (e.g. "ARCHIVE") — only for option subsections
flags array Extracted command-line flags with descriptions
flags[].flag string Short flag (e.g. "-c")
flags[].long string|null Long flag (e.g. "--create")
flags[].arg string|null Argument placeholder
flags[].description string Flag description (single line)
examples array Command usage examples (from EXAMPLES section)
see_also array Cross-references to related man pages
see_also[].name string Related command name
see_also[].section string Related command section
see_also[].url string JSON API URL for related command

Search Response

{
  "mode": "search",
  "query": "cron",
  "count": 5,
  "results": [
    {
      "name": "cron",
      "section": "8",
      "description": "daemon to execute scheduled commands"
    },
    {
      "name": "crontab",
      "section": "1",
      "description": "maintain crontab files for individual users"
    }
  ]
}

MCP Wrapper Format

When using /mcp endpoint or MCP POST, the response is wrapped:

{
  "content": [
    {
      "type": "text",
      "text": "<full JSON response as string>"
    }
  ],
  "structuredContent": {
    "command": "tar",
    "section": "1",
    "mode": "man",
    "summary": "tar - An archiving utility",
    "synopsis": "tar [OPTION...] [FILE]...",
    "flags": [...],
    "examples": [...],
    "see_also": [...],
    "section_outline": [
      {
        "name": "NAME",
        "lines": 1,
        "subsections": []
      },
      {
        "name": "OPTIONS",
        "lines": 45,
        "subsections": [
          {"name": "-c, --create", "lines": 3, "flag": "-c", "long": "--create"},
          {"name": "-f, --file=ARCHIVE", "lines": 5, "flag": "-f", "long": "--file", "arg": "ARCHIVE"}
        ]
      }
    ]
  }
}

The content[0].text field contains the full JSON response as a string (for LLM consumption). The structuredContent field provides programmatic access to key metadata (for agent tooling).


REST API Endpoints

For clients that don't support MCP, phpMan exposes REST endpoints with identical structured output.

JSON API

Append /json to any detail page URL, or send Accept: application/json header:

# Man page with structured sections
curl "https://www.chedong.com/phpMan.php/man/ls/1/json"

# Apropos search results
curl "https://www.chedong.com/phpMan.php/search/git/json"

# Accept header (works on any URL)
curl -H "Accept: application/json" "https://www.chedong.com/phpMan.php/man/bash"

MCP Format (REST GET)

The /mcp format suffix wraps JSON output in MCP's content array — making REST GET and MCP POST responses identical:

# Same man page, same output format as MCP POST tools/call
curl "https://www.chedong.com/phpMan.php/man/ls/1/mcp"
# → {"content":[{"type":"text","text":"..."}],"structuredContent":{...}}

# Search with MCP format
curl "https://www.chedong.com/phpMan.php/search/cron/mcp"

# Perldoc with MCP format
curl "https://www.chedong.com/phpMan.php/perldoc/Digest::MD5/mcp"

This means any MCP client can GET /man/ls/1/mcp and parse the result identically to POST /mcp tools/call.

TLDR Endpoint

Generate cheatsheet-style summaries from man pages:

curl "https://www.chedong.com/phpMan.php/tldr/tar"

Returns Markdown with:

  • Command summary
  • 5-8 practical examples
  • Common flags with descriptions
  • Auto-generated --help and --version examples

What's New in v2.1

Cross-Platform Width Control

  • perldoc: Uses pod2text -w N pipeline for consistent output width on Linux and macOS
  • man (macOS/BSD): MANWIDTH fallback when groff -Tutf8 is unavailable
  • man (Linux): MANROFFOPT=-rLL=Nn + groff -Tutf8 for precise width

Roadmap

See docs/PLAN.md for the full project plan:

  • pydoc / ri — Python and Ruby documentation support (pydoc3 / ri)
  • LLM-powered — AI translation (identifier-preserving), cheat sheets, example generation
  • Search — Alphabetic sidebar navigation for large index pages (>150 entries)
  • MCP — Streaming output, error standardization, dynamic tool discovery
  • I18N — LANG-based locale support + AI fallback translation

Features

  • Man Pages — Browse any Unix/Linux manual page with -Tutf8 output (SGR bold/underline support)
  • Perldoc — Read Perl module documentation in-browser
  • Info Pages — View GNU info documentation
  • Apropos Search — Full-text search across man page summaries
  • TOC Sidebar — Two-level floating table of contents for navigation
  • Markdown Output — Append /markdown for machine-readable format
  • JSON API — Append /json for structured JSON output with semantic fields
  • MCP Format — Append /mcp for MCP-compatible output
  • MCP Server — Model Context Protocol endpoint for AI agent integration
  • TLDR Endpoint — Append /tldr for cheatsheet-style summaries
  • SEO Optimized — Canonical URLs, meta description, robots directives
  • Clean URLs — PATH_INFO routing: /man/ls/1

Comparison: man / Info / Perldoc Modes

phpMan supports three Unix documentation retrieval methods, each corresponding to different system commands, data sources, and documentation format specifications.

1. man Mode

Item Description
System Command man -Tutf8 <argument>
Data Source /usr/share/man/, /usr/local/share/man/ — files with .1.gz, .3pm.gz etc.
Source Format troff / groff (AT&T typesetting language), original content contains overstrike sequences (e.g., W^HWA^HAR^HRN^H...)
Standard man-pages(7) — 9 sections: 1=user commands, 2=system calls, 3=C library functions, 4=device files, 5=file formats, 6=games, 7=miscellaneous, 8=system administration, 9=kernel routines
Internal Structure Flat document per page, fixed sections include NAME, SYNOPSIS, DESCRIPTION, OPTIONS, EXAMPLES, SEE ALSO, etc.
Subsections Supports second-level subsections (.SS macro → bold/underline), fully displayed in TOC

2. info Mode

Item Description
System Command info <argument>
Data Source /usr/share/info/ — files with .info.gz, .info
Source Format Texinfo (GNU documentation format), original content includes typesetting markers (* Menu:, section numbers 4.1, cross-references (node))
Standard Texinfo → can generate PDF, HTML, and info. Node is the basic unit, with hypertext links via (node) forming a documentation tree
Internal Structure Tree-like node structure, can contain submenu nodes, supports jump navigation
Subsections Plain text output from info has only section numbers (3.1, 3.2) and indentation, no identifiable explicit heading macros, so TOC shows only first level

3. perldoc Mode

Item Description
System Command perldoc <module>perldoc -f <function>perldoc -q <regex> (three-level fallback)
Data Source .pod files in Perl installation paths
Source Format POD (Plain Old Documentation), Perl documentation format, uses =head1, =head2, =over, =item markers
Standard perlpod(1)=head1 for major sections, =head2 for subsections
Internal Structure Flat document with clear =head1=head2 hierarchy
Subsections Supports second-level subsections (=head2), fully displayed in TOC

4. Cross-Comparison

Dimension man info perldoc
Ecosystem BSD / Unix general GNU project specific Perl language specific
Source Format troff / groff Texinfo POD
Overstrike Output ✅ Yes ❌ No ❌ No (but has ANSI escapes)
Second-level Headings .SS → bold/underline Section number + indent =head2 → Title Case
TOC Depth ✅ Full two levels ❌ First level only ✅ Full two levels
Linking Capability Weak (cross-reference name(sec)) Strong (node tree (node) navigation) Weak (module reference Module::Name)
Typical Content Command references, syscalls, config formats GNU project complete manuals (tutorials, concepts) Perl module API references

ℹ️ About info Subsections: info mode currently cannot generate a second-level TOC because info plain text output only has section numbers (e.g., 3.1 Simple options), lacking explicit heading markers like man's .SS or perldoc's =head2. Support can be added by extending the heading recognition logic.

Check Out Source Code

HTTPS (read-only)

git clone https://git.code.sf.net/p/phpunixman/code phpman

SSH (developers)

git clone ssh://chedong@git.code.sf.net/p/phpunixman/code.git phpman

Quick Start

Deploy phpMan on any PHP 8.x server with a single file:

# Clone the repository
git clone https://git.code.sf.net/p/phpunixman/code phpman

# Copy to your web server's document root
cp phpman/phpMan.php /var/www/html/

# Access in browser
# https://your-server/phpMan.php

For Apache 2.x, ensure AcceptPathInfo On is configured to enable clean URL routing.

Publish Updates

The repository includes a generic Makefile for local checks, staging deployment, production deployment, and release upload. Site-specific values are loaded from .deploy.mk, which is intentionally ignored by git.

Create your local deployment config from the example:

cp .deploy.mk.example .deploy.mk

Then edit .deploy.mk for your server:

TEST_USER = your-user
TEST_HOST = example.com
TEST_PORT = 22
TEST_PATH = /home/your-user/example.com/test
TEST_URL  = https://example.com/test/phpMan.php

DEMO_USER = your-user
DEMO_HOST = example.com
DEMO_PORT = 22
DEMO_PATH = /home/your-user/example.com
DEMO_URL  = https://example.com/phpMan.php

1. Test Locally

make test

2. Commit and Push to SourceForge Git

git add phpMan.php README.md Makefile .deploy.mk.example .gitignore
git commit -m "description of changes"
git push origin master

3. Update Staging Demo

make deploy

This deploys only phpMan.php to the staging path configured by DEMO_TEST.

4. Update Production Demo

make release
make deploy-verify

⚠️ Do not overwrite index.php — only update phpMan.php.

5. Update Static Site (SourceForge project web)

scp index.html chedong@web.sourceforge.net:/home/project-web/phpunixman/htdocs/index.html

The index.html is a static project introduction page with screenshot and a demo link pointing to chedong.com/phpMan.php.

6. Upload Release

Upload the compressed archive and README to SourceForge File Release System:

make upload-release

README.md will be rendered below the file listing on the Files page. Or upload manually via: https://sourceforge.net/projects/phpunixman/files/

License

GNU General Public License v2.0 — see copyright page.

Author

Che Dong — https://www.chedong.com/

Source: README.md, updated 2026-05-31