Skip to main content
Glama
maschmann

symfony-php-mcp

by maschmann

symfony-php-mcp

A production-ready Model Context Protocol (MCP) server that bridges your Symfony/PHP project with LLMs such as Claude. It exposes tools that let the AI read your project's routes, services, Twig templates, and PHP source code — without ever needing direct filesystem access from the LLM itself.

Claude Desktop / Claude Code
        │
        │  MCP (stdio)
        ▼
symfony-php-mcp  ──► reads ──► composer.json, symfony.lock, services.yaml, *.twig
                 ──► runs  ──► php bin/console debug:router / debug:container

Table of Contents


Related MCP server: phpustik MCP Server

Features

Tool

What it does

PHP needed?

get_project_overview

Reads composer.json + symfony.lock – PHP version, Symfony version, all packages

No

find_route

Runs debug:router --format=json, filters by URL pattern and HTTP method

Yes

analyze_twig

Finds a .twig file and extracts extends, include, block, macros

No

list_services

Reads config/services.yaml or runs debug:container --format=json

Optional

read_code_context

Reads a PHP file, strips doc-block comments to save tokens

No


Quick Start

# Requires uv — https://docs.astral.sh/uv/
SYMFONY_PROJECT_ROOT=/path/to/your/symfony/app uvx symfony-php-mcp

The server speaks MCP over stdio and is designed to be launched by your MCP client (Claude Desktop, Claude Code, etc.), not run manually.


Installation

uvx runs the package from the PyPI / GitHub registry with no permanent install:

// claude_desktop_config.json
{
  "mcpServers": {
    "symfony": {
      "command": "uvx",
      "args": ["symfony-php-mcp"],
      "env": {
        "SYMFONY_PROJECT_ROOT": "/path/to/your/symfony-app"
      }
    }
  }
}

Install from GitHub (before it's on PyPI):

{
  "mcpServers": {
    "symfony": {
      "command": "uvx",
      "args": ["--from", "git+https://github.com/maschmann/symfony-php-mcp", "symfony-mcp"],
      "env": {
        "SYMFONY_PROJECT_ROOT": "/path/to/your/symfony-app"
      }
    }
  }
}

Via local clone

git clone https://github.com/maschmann/symfony-php-mcp
cd symfony-php-mcp
uv sync
{
  "mcpServers": {
    "symfony": {
      "command": "uv",
      "args": ["run", "--project", "/path/to/symfony-php-mcp", "symfony-mcp"],
      "env": {
        "SYMFONY_PROJECT_ROOT": "/path/to/your/symfony-app"
      }
    }
  }
}

Configuration

Configuration is resolved in priority order: environment variables → .symfony-mcp.json → built-in defaults.

Environment Variables

Set these in your MCP client's env block.

Variable

Default

Description

SYMFONY_PROJECT_ROOT

current working directory

Required. Absolute path to your Symfony project (the directory containing composer.json).

PHP_EXECUTABLE

php

PHP binary or wrapper command. Use ddev php, lando php, or a full path like /usr/bin/php8.3.

DOCKER_CONTAINER

(none)

Docker container name. When set, commands run as docker exec <container> php …. Takes precedence over PHP_EXECUTABLE.

DOCKER_EXEC_USER

(none)

Optional -u <user> for docker exec. Useful when the container runs PHP as www-data.

CONSOLE_PATH

bin/console

Path to bin/console relative to SYMFONY_PROJECT_ROOT. Rarely needs changing.

COMMAND_TIMEOUT

30

Seconds before a PHP subprocess is killed. Increase for large projects or slow containers.

Project-local config file (.symfony-mcp.json)

Place this file in your Symfony project root to commit PHP runtime preferences alongside the project code. Great for teams using DDEV or Docker Compose.

{
  "php_executable": "php",
  "docker_container": null,
  "docker_exec_user": null,
  "console_path": "bin/console",
  "command_timeout": 30
}

Example for a DDEV project:

{
  "php_executable": "ddev php",
  "command_timeout": 60
}

Example for a Docker Compose project:

{
  "docker_container": "my-project-php-1",
  "docker_exec_user": "www-data",
  "command_timeout": 45
}

Configuration priority

Environment variables (MCP client env block)
        ↓  (override)
.symfony-mcp.json  (in SYMFONY_PROJECT_ROOT)
        ↓  (override)
Built-in defaults

Environment variables always win. This means you can commit a .symfony-mcp.json with sensible defaults for your team while still being able to override them per-machine via env vars.


Claude Desktop Setup

The claude_desktop_config.json file lives at:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json

  • Windows: %APPDATA%\Claude\claude_desktop_config.json

  • Linux: ~/.config/Claude/claude_desktop_config.json

Local PHP

{
  "mcpServers": {
    "symfony": {
      "command": "uvx",
      "args": ["symfony-php-mcp"],
      "env": {
        "SYMFONY_PROJECT_ROOT": "/home/alice/projects/my-symfony-app"
      }
    }
  }
}

Docker

Works with any Docker Compose project. The container must be running when Claude Desktop starts (or before you use the tools).

{
  "mcpServers": {
    "symfony": {
      "command": "uvx",
      "args": ["symfony-php-mcp"],
      "env": {
        "SYMFONY_PROJECT_ROOT": "/home/alice/projects/my-symfony-app",
        "DOCKER_CONTAINER": "my-symfony-app-php-1",
        "DOCKER_EXEC_USER": "www-data"
      }
    }
  }
}

Finding your container name: run docker ps and look at the NAMES column.

DDEV

{
  "mcpServers": {
    "symfony": {
      "command": "uvx",
      "args": ["symfony-php-mcp"],
      "env": {
        "SYMFONY_PROJECT_ROOT": "/home/alice/projects/my-symfony-app",
        "PHP_EXECUTABLE": "ddev php"
      }
    }
  }
}

Alternatively, commit a .symfony-mcp.json to your project:

{
  "php_executable": "ddev php"
}

Then the MCP config only needs SYMFONY_PROJECT_ROOT.

Lando

{
  "mcpServers": {
    "symfony": {
      "command": "uvx",
      "args": ["symfony-php-mcp"],
      "env": {
        "SYMFONY_PROJECT_ROOT": "/home/alice/projects/my-symfony-app",
        "PHP_EXECUTABLE": "lando php"
      }
    }
  }
}

Sail

Laravel Sail is a thin Docker wrapper but the pattern works for Symfony projects using a similar setup:

{
  "env": {
    "SYMFONY_PROJECT_ROOT": "/home/alice/projects/my-project",
    "DOCKER_CONTAINER": "my-project-laravel.test-1"
  }
}

Tools Reference

get_project_overview

Returns a Markdown summary of the project. Call this first to give the LLM context before using other tools.

Parameters: none

Returns:

# Symfony Project: `acme/store`
> An e-commerce platform built with Symfony

## Runtime
| Key | Value |
|-----|-------|
| PHP requirement | `>=8.2` |
| Symfony version | `7.1.3` |
| APP_ENV | `dev` |

## Installed Packages
### Symfony Components
| Package | Version | Dev? |
...

find_route

Finds routes matching a URL pattern or route name.

Parameters:

Parameter

Type

Required

Description

url_pattern

string

Yes

Substring or regex to match against route paths and names. E.g. /api/user, user_show, ^/admin

method

string

No

HTTP method filter: GET, POST, PUT, PATCH, DELETE. Empty = any.

Example:

Tool: find_route
url_pattern: /api/user
method: GET
Found **3** route(s) matching `/api/user`

| Route Name | Path | Methods | Controller |
|------------|------|---------|------------|
| `api_user_list` | `/api/users` | `GET` | `UserController::list` |
| `api_user_show` | `/api/users/{id}` | `GET` | `UserController::show` |
| `api_user_me`   | `/api/user/me`    | `GET` | `UserController::me`   |

Requires: PHP + bin/console


analyze_twig

Analyses a Twig template without running PHP.

Parameters:

Parameter

Type

Required

Description

template_name

string

Yes

Template name as used in Twig, or a partial name. E.g. user/show.html.twig, show, user/

Example:

Tool: analyze_twig
template_name: user/show.html.twig
## Template: `templates/user/show.html.twig`

### Inheritance
Extends: `base.html.twig`

### Included / Embedded Templates
| Type | Template |
|------|----------|
| include | `_partials/user_card.html.twig` |
| include | `_partials/breadcrumb.html.twig` |

### Defined Blocks
`title`, `content`, `scripts`

### Template Variables
`user`, `posts`, `pagination`

list_services

Lists service definitions from config/services.yaml or the compiled container.

Parameters:

Parameter

Type

Default

Description

filter_pattern

string

""

Regex/substring to filter by service ID or class. E.g. App\\Service, mailer, doctrine

use_container_debug

bool

false

Use debug:container --format=json instead of YAML. Required to see auto-wired / framework services.

Example – find all mailer services:

Tool: list_services
filter_pattern: mailer
use_container_debug: true

read_code_context

Reads a PHP file with optional comment stripping to reduce token usage.

Parameters:

Parameter

Type

Default

Description

file_path

string

Path relative to project root. E.g. src/Controller/UserController.php

strip_doc_comments

bool

true

Strip /** … */ and /* … */ blocks. Saves ~20-40% tokens on typical controllers.

strip_line_comments

bool

false

Also strip // comments. Use when you need maximum token efficiency.

Example:

Tool: read_code_context
file_path: src/Controller/UserController.php
## `src/Controller/UserController.php`

| Property | Value |
|----------|-------|
| Original  | 187 lines / 6,842 chars |
| After processing | 134 lines / 4,201 chars |
| Token savings | ~39% (block comments stripped) |

```php
  1 | <?php
  2 |
  3 | namespace App\Controller;
...

Docker / Container Environments (in depth)

How command routing works

When DOCKER_CONTAINER is set, every PHP/console invocation becomes:

docker exec [-u <DOCKER_EXEC_USER>] <DOCKER_CONTAINER> php bin/console <args>

When PHP_EXECUTABLE is set to ddev php:

ddev php bin/console <args>

The server never modifies the project files inside the container.

Docker Compose tips

  1. Container name – use docker ps to find the exact name. For docker compose, it's usually <project>-<service>-1.

  2. File pathsSYMFONY_PROJECT_ROOT should point to the host path since the server reads files directly via the Python filesystem layer. Only debug:router / debug:container commands run inside the container.

  3. Working directory – commands are run in SYMFONY_PROJECT_ROOT on the host. If your container mounts the project at a different path, set CONSOLE_PATH accordingly — or ensure bin/console is accessible from the host path.

  4. Container not running – the server will return a helpful error. Start your containers first: docker compose up -d.

DDEV tips

# List DDEV projects
ddev list

# Ensure the project is running
ddev start

# Test PHP is accessible
ddev php --version

.symfony-mcp.json for DDEV:

{
  "php_executable": "ddev php",
  "command_timeout": 60
}

Lando tips

# Ensure the project is running
lando start

# Test PHP is accessible
lando php --version

.symfony-mcp.json for Lando:

{
  "php_executable": "lando php"
}

Development

# Clone
git clone https://github.com/maschmann/symfony-php-mcp
cd symfony-php-mcp

# Install dependencies (requires uv — https://docs.astral.sh/uv/)
uv sync

# Run the server (will block waiting for MCP stdio input)
uv run symfony-php-mcp

# Run tests
uv run pytest

# Lint
uv run ruff check src/
uv run ruff format --check src/

Project structure

src/symfony_mcp/
├── server.py        # FastMCP server, lifespan, tool decorators, main()
├── config.py        # ServerConfig: env vars + .symfony-mcp.json merge logic
├── executor.py      # PhpExecutor: subprocess wrapper with Docker/wrapper support
├── indexer.py       # SymbolIndex: PHP regex scanner + JSON persistence
└── tools/
    ├── project.py   # get_project_overview
    ├── router.py    # find_route
    ├── twig.py      # analyze_twig
    ├── services.py  # list_services
    ├── code.py      # read_code_context
    └── index.py     # build_index, find_symbol, search_code

Symbol index

The index is stored at <symfony-project>/.symfony-mcp-index.json. Add it to the project's .gitignore:

# symfony-php-mcp symbol index
.symfony-mcp-index.json

Typical workflow:

1. build_index                      — first time, or after major refactors
2. find_symbol "UserController"     — get file + line number instantly
3. read_code_context src/...php     — read the implementation

The index updates incrementally (only changed files are re-scanned), so calling build_index after saving a few files is fast.

Adding a new tool

  1. Create src/symfony_mcp/tools/my_tool.py with a plain function.

  2. Register it in server.py with @mcp.tool().

  3. Add a docstring – FastMCP uses it as the tool description.


Troubleshooting

"Binary not found: 'php'"

PHP is not in the PATH used by the MCP server process.

Fix options:

  • Install PHP: apt install php-cli / brew install php

  • Use a full path: PHP_EXECUTABLE=/usr/bin/php8.3

  • Use Docker: DOCKER_CONTAINER=my-php-container

  • Use DDEV: PHP_EXECUTABLE=ddev php

"Symfony console not found"

SYMFONY_PROJECT_ROOT is pointing to the wrong directory, or bin/console is missing.

Fix: Make sure SYMFONY_PROJECT_ROOT is the directory that contains both composer.json and bin/console.

ls /your/project/bin/console   # should exist

"Command timed out"

The PHP command took longer than COMMAND_TIMEOUT seconds.

Fix: Increase the timeout:

// .symfony-mcp.json
{ "command_timeout": 120 }

Or set COMMAND_TIMEOUT=120 in the MCP env block.

"Cannot inspect container"

The Docker container is not running.

Fix:

docker compose up -d           # Docker Compose
ddev start                     # DDEV
lando start                    # Lando

Claude Desktop doesn't see the server

  1. Restart Claude Desktop after editing claude_desktop_config.json.

  2. Check the MCP server logs in Claude Desktop → Settings → Developer → MCP Servers.

  3. Run the server manually to check for errors:

    SYMFONY_PROJECT_ROOT=/path/to/project uvx symfony-php-mcp

    It should start silently (waiting for stdio input). Any error on startup will print to stderr.

"Error parsing config/services.yaml"

Your services.yaml has a syntax error or uses YAML features not supported by PyYAML.

Fix: Use use_container_debug=true in list_services as a fallback:

Tool: list_services
filter_pattern: App\
use_container_debug: true

License

MIT — see LICENSE.

Available Tools

8 tools
analyze_twigA

Analyse a Twig template and return its structural metadata.

No PHP execution required – pure filesystem analysis.

Extracts:

  • extends parent (inheritance chain)

  • {% include %} and {% embed %} directives

  • {% import %} and {% from ... import %} macro imports

  • {% block %} definitions

  • Template variables referenced in {{ }} expressions

Args: template_name: Template path as used in Twig (e.g. "user/show.html.twig") or a partial name (e.g. "show" or "user/show"). The templates/ directory is searched recursively.

Returns a structured Markdown report.

ParametersJSON Schema
NameRequiredDescriptionDefault
template_nameYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.6/5.0
Behavior4/5

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

No annotations are provided, so the description carries full weight. It explicitly states that analysis is filesystem-only and lists what it extracts (inheritance, includes, imports, blocks, variables). It could mention side-effect-free behavior more explicitly, but is largely transparent.

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 well-structured: purpose first, then key extracted elements in a bullet list, then parameter details. Every sentence adds value without redundancy.

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

Completeness5/5

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

Given the tool's simplicity (one parameter) and the presence of an output schema, the description covers all necessary aspects: purpose, parameter semantics, and return type (structured Markdown report). It is complete.

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

Parameters5/5

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

The schema provides no description for the single parameter (0% coverage), but the description adds detailed guidance: valid formats (full path, partial name) and recursive search behavior. This fully compensates for the schema gap.

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

Purpose5/5

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

The description clearly states the tool's purpose: analyze Twig templates and return structural metadata. It is specific and distinct from sibling tools which focus on code searching, routing, or project overview.

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

Usage Guidelines4/5

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

The description explains that no PHP execution is required, implying it is safe and fast for static analysis. It doesn't explicitly mention when not to use it or contrast with alternatives, but the context is clear enough for an agent.

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

build_indexA

Scan PHP files and build (or update) the symbol index.

The index stores all classes, interfaces, traits, enums, and their methods so that find_symbol can locate any symbol instantly without re-scanning.

The index is persisted to /.symfony-mcp-index.json and loaded automatically on next server start. Only changed files are re-scanned (incremental), so subsequent calls are fast.

Args: directories: Directories to scan, relative to the project root. Default: auto-detected (src/, app/, lib/). Example: ["src", "lib"] force: Re-scan every file even if it hasn't changed. Use this after a major refactor or rename.

Run this once after pointing the server at a new project, then again after significant code changes.

ParametersJSON Schema
NameRequiredDescriptionDefault
directoriesNo
forceNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A5/5.0
Behavior5/5

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

No annotations provided; description carries full burden. Discloses persistence to a JSON file, automatic loading, incremental re-scanning, and force option. No mention of destructive side effects or auth needs; adequate transparency.

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?

Well-structured: headline, bullet points for index content, note on persistence/incremental, then Args section. Every sentence adds value; no fluff.

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

Completeness5/5

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

With sibling tools present, description links to find_symbol. Output schema exists (not shown) so return value explanation unnecessary. Complete for a build/index tool with good annotations.

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

Parameters5/5

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

Despite 0% schema description coverage, description explains both parameters: directories (default and example) and force (use case for major refactor). Adds meaning beyond the bare schema.

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

Purpose5/5

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

Clearly states the tool scans PHP files and builds/updates a symbol index. Lists what the index stores (classes, interfaces, traits, enums, methods) and relates to sibling tool find_symbol for lookup. Verb 'scan and build' with resource 'symbol index' is specific and distinct from siblings.

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

Usage Guidelines5/5

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

Explicitly advises to run once after project setup and after significant code changes. Implicitly contrasts with find_symbol (no need to re-scan for lookups). Describes incremental behavior to guide efficient use.

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

find_routeA

Find Symfony routes matching a URL pattern or route name.

Runs php bin/console debug:router --format=json and filters the results.

Args: url_pattern: Substring or regex to match against route paths and route names. Examples: "/api/users", "user_show", "^/admin" method: Optional HTTP method filter (GET, POST, PUT, PATCH, DELETE). Empty string = no filter (matches all methods).

Returns a Markdown table with: route name, path, allowed methods, controller. For single matches, the full route definition is included.

Requires PHP and bin/console to be accessible (configure via DOCKER_CONTAINER or PHP_EXECUTABLE if using Docker/DDEV/Lando).

ParametersJSON Schema
NameRequiredDescriptionDefault
url_patternYes
methodNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.6/5.0
Behavior5/5

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

Discloses the underlying console command, requirements for PHP environment, return format (Markdown table with specific columns), and behavior for single matches. No annotations are provided, so the description carries the full burden.

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

Conciseness4/5

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

Well-structured with purpose first, then method, parameters, output, and requirements. No redundancy, but could be slightly more concise.

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

Completeness5/5

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

Covers prerequisites (PHP access), parameters, output format, and behavior for single vs multiple matches. Completeness is appropriate for a tool that runs an external command.

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

Parameters4/5

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

With 0% schema description coverage, the description adds substantial meaning: explains url_pattern as substring or regex with examples, and method as optional filter with examples. Slightly more detail on regex format could improve, but overall effective.

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

Purpose5/5

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

The description clearly states it finds Symfony routes matching a URL pattern or route name, specifying the command used. This distinguishes it from sibling tools like search_code and find_symbol.

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

Usage Guidelines4/5

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

Provides explicit examples for url_pattern and method parameter, indicating when to use. However, it does not explicitly state when not to use or compare to alternatives.

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

find_symbolA

Search the symbol index for a PHP class, interface, trait, enum, or method.

Returns file paths and line numbers — use the result directly with read_code_context to inspect the implementation.

Requires build_index to have been run at least once.

Args: name: Name to search for (case-insensitive substring or full name). Examples: "UserController", "UserRepo", "findByEmail", "App\Entity" kind: Optional filter. One of: class, interface, trait, enum, method. Empty = search all symbol types.

Typical workflow:

  1. build_index — index the project (once, or after big changes)

  2. find_symbol "Foo" — locate the file and line

  3. read_code_context — read the file for full implementation

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYes
kindNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.7/5.0
Behavior5/5

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

No annotations provided, so description fully discloses behavior: case-insensitive search, optional kind filter, and return of file paths and line numbers. No hidden side effects.

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?

Well-structured with a brief purpose sentence, parameter explanations, and a clear workflow. Every sentence adds value, no redundancy.

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?

Covers prerequisites, parameters, and workflow. Output format is mentioned but not detailed; however, an output schema exists to fill that gap.

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

Parameters5/5

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

0% schema coverage, but description adds detailed meaning: 'name' is case-insensitive substring with examples; 'kind' lists allowed values and default behavior. Crucial beyond schema.

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

Purpose5/5

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

The description clearly states the tool searches for PHP symbols (class, interface, trait, enum, method) and returns file paths and line numbers, distinguishing it from siblings like search_code.

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

Usage Guidelines4/5

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

Explicitly mentions prerequisite (build_index) and provides a typical workflow. Lacks explicit alternatives or when-not-to-use, but context is clear.

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

get_project_overviewA

Return a Markdown overview of the Symfony project.

Reads composer.json, symfony.lock (or composer.lock), and .env to report:

  • PHP version requirement

  • Exact Symfony version installed

  • All installed packages, grouped by category

  • PSR-4 autoload namespaces

  • Composer scripts

  • APP_ENV setting

Call this tool first before using other tools to understand the project.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.4/5.0
Behavior4/5

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

Discloses that it reads specific files (composer.json, symfony.lock, .env) and reports certain information. As a read-only operation with no side effects, this is adequate, though it doesn't explicitly state it is read-only or mention failure scenarios.

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

Conciseness4/5

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

Description is structured with bullet points and front-loaded with purpose. Every sentence adds value, though the bullet list could be slightly more concise without losing clarity.

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

Completeness5/5

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

Given no parameters and an output schema exists, the description fully explains the output content and provides usage context (call first). It is complete for a tool meant for initial project overview.

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

Parameters4/5

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

No parameters exist, so schema coverage is 100%. The description correctly omits parameter details as none are needed, meeting the baseline for zero-parameter tools.

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

Purpose5/5

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

Clearly states the output is a Markdown overview of the Symfony project, listing specific data points (PHP version, Symfony version, packages, etc.). It distinguishes itself by instructing to call this tool first, differentiating it from sibling tools.

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

Usage Guidelines4/5

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

Explicitly says 'Call this tool first before using other tools to understand the project,' providing clear context. It doesn't mention when not to use it, but this is acceptable given its role as an initial discovery tool.

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

list_servicesA

List Symfony service definitions.

Two modes:

  1. YAML mode (default, fast, no PHP required): Reads config/services.yaml directly. Shows explicitly defined services.

  2. Container debug mode (use_container_debug=true): Runs php bin/console debug:container --format=json. Shows the full compiled container including auto-wired services – useful for finding framework/bundle services.

Args: filter_pattern: Regex or substring to filter service IDs or class names. Examples: "App\Service", "mailer", "doctrine" Empty = show all defined services. use_container_debug: Set to true to query the full compiled DI container. Requires PHP and bin/console to be accessible.

Returns a Markdown table with: service ID, class, public flag, tags.

ParametersJSON Schema
NameRequiredDescriptionDefault
filter_patternNo
use_container_debugNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.6/5.0
Behavior4/5

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

No annotations provided, so description carries full burden. It discloses modes, prerequisites, and return format (Markdown table). Performance characteristics are mentioned, but no explicit statement about non-destructiveness or side effects.

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?

Well-structured with clear headings, concise yet informative. No unnecessary words; each sentence adds value.

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

Completeness5/5

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

For a tool with 2 optional parameters and an output schema, the description covers usage, modes, filter syntax, and result format completely. No gaps.

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

Parameters5/5

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

Schema has 0% coverage (no parameter descriptions), but the tool description thoroughly explains both parameters, including examples and behavior for default values. Highly compensates for missing schema info.

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

Purpose5/5

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

The description clearly states it lists Symfony service definitions, specifying two modes. The verb 'list' and resource 'service definitions' are explicit. Distinguishes from sibling tools (e.g., find_route, search_code) by domain focus.

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

Usage Guidelines4/5

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

Provides detailed guidance on when to use each mode (YAML vs container debug) with prerequisites. However, no explicit comparison to alternative sibling tools, though context makes it less necessary.

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

read_code_contextA

Read a file from the Symfony project, with optional comment stripping.

Stripping PHPDoc / block comments (/* ... */) significantly reduces token usage without losing functional information – use strip_doc_comments=true (the default) for faster, cheaper analysis.

Args: file_path: Path relative to the project root. Examples: "src/Controller/UserController.php" "src/Entity/User.php" Absolute paths inside the project are also accepted. strip_doc_comments: Remove /** ... / and / ... */ blocks. Default: true. strip_line_comments: Also remove // single-line comments. Default: false (inline comments are useful context).

Returns the file content with line numbers and a token-savings summary.

Security: only files inside the project root can be read (path traversal is blocked).

ParametersJSON Schema
NameRequiredDescriptionDefault
file_pathYes
strip_doc_commentsNo
strip_line_commentsNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.6/5.0
Behavior5/5

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

With no annotations provided, the description fully covers behavioral traits: it explains the default stripping behavior, token savings, security (path traversal blocked), and return format (line numbers, savings summary). No contradiction.

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 well-structured with an Args section, Returns line, and Security note. Every sentence adds value without redundancy. It is concise yet complete.

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

Completeness5/5

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

The description covers the tool's purpose, parameters, behavior, return content, and security. Given the low complexity and presence of an output schema (though not shown), the description is sufficiently complete.

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

Parameters5/5

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

Schema coverage is 0%, but the description adds extensive meaning: file_path includes examples and accepted formats, strip_doc_comments explains benefits and default, strip_line_comments clarifies context. This compensates fully.

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

Purpose5/5

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

The description clearly states the tool reads a file from the Symfony project with optional comment stripping. The verb 'Read' and resource 'file from the Symfony project' are specific, and it distinguishes from siblings like analyze_twig or search_code.

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 description offers some usage guidance (e.g., using strip_doc_comments=true for faster analysis) and security constraints, but does not explicitly state when to use this tool versus siblings. It lacks direct comparisons or when-not scenarios.

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

search_codeA

Live regex/substring search across project files.

No index required — scans files directly each time. Useful for finding usages, checking for patterns, or searching non-PHP files.

Args: pattern: Python regex or plain substring to search for. Examples: "UserRepository", "findByEmail(", "#[Route" path_glob: Glob relative to project root. Default: /*.php Other examples: src//.php, templates/**/.twig, config/**/*.yaml, **/*.php context_lines: Lines of surrounding context to show (0–5). Default: 2. max_results: Max matching snippets to return (1–200). Default: 30.

Returns highlighted snippets with file path and line number.

ParametersJSON Schema
NameRequiredDescriptionDefault
patternYes
path_globNo**/*.php
context_linesNo
max_resultsNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.5/5.0
Behavior4/5

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

No annotations, description explains behavior: scans files directly, no index, returns highlighted snippets with file path and line. Adequate for understanding operation.

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?

Concise intro followed by clear bullet-like parameter explanations. No superfluous text. Well-structured and front-loaded.

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?

Covers all 4 parameters with defaults, output description. Missing potential performance notes or more complex examples, but sufficient given output schema exists.

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

Parameters5/5

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

Schema coverage 0%, but description fully compensates: explains pattern with examples, path_glob with defaults and examples, context_lines range, max_results range. Adds substantial meaning.

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

Purpose5/5

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

Clear verb 'search' and resource 'project files' with specifics (regex/substring, live, no index). Distinguishes from siblings like find_symbol and analyze_twig.

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

Usage Guidelines4/5

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

Provides scenarios: 'finding usages, checking for patterns, searching non-PHP files.' Implicitly suggests one-off use due to 'no index' mention. Lacks explicit comparisons to siblings.

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

TDQS

A4.6/5.0
Disambiguation5/5

Each tool has a clearly distinct purpose: Twig analysis, index building, route finding, symbol lookup, project overview, service listing, file reading, and regex search. No overlaps or ambiguity.

Naming Consistency5/5

All tool names follow a consistent verb_noun pattern (e.g., analyze_twig, build_index, find_route) and use snake_case uniformly, making the set predictable.

Tool Count5/5

With 8 tools, the server covers the essential operations for Symfony project inspection without being excessive or sparse. The count is well-scoped for its purpose.

Completeness4/5

The tool surface covers core read/inspection tasks (routes, services, symbols, code, Twig), but lacks a tool to list all Twig templates or other structural elements, a minor gap.

Maintenance

ActivityInactive
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • A
    license
    B
    quality
    D
    maintenance
    Enables AI assistants to deeply interact with the PHP ecosystem, including runtime, static analysis, security scanning, testing, Composer, and frameworks like Laravel and Symfony. It exposes over 30 tools, 8 resources, and 7 prompts via MCP, allowing natural language commands to run PHP linting, static analysis, audits, tests, and project initialization.
    41
    MIT
  • F
    license
    A
    quality
    D
    maintenance
    Model Context Protocol (MCP) server for Octopilot — enables AI agents to detect, generate, build, and wire up new repositories end-to-end using the Octopilot CI/CD toolchain.
    7

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/maschmann/symfony-php-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server