Skip to main content
Glama
NBNBTM

PDDL MCP Server

by NBNBTM

PDDL MCP Server

PDDL MCP Server is a personal MCP backend project for turning natural-language planning requests or explicit PDDL files into executable Fast Downward plans.

It is designed as a clean single-version planning service: understand the task, match domain knowledge, generate PDDL, run a planner, validate the result, and return a structured MCP response with artifacts.

Project Context and Contribution

I designed and implemented this repository independently from start to finish, including the natural-language/PDDL workflow, Fast Downward integration and debugging, domain templates, stable tool responses, artifact handling, validation, modular src package structure, tests, CI, security guidance, release documentation, and demo assets.

My algorithm engineering internship at UniDT Co., Ltd. is relevant professional context for my interest in automated planning, but this repository is my independently developed personal project. It is not company code, does not require or imply company authorization, and does not contain employer credentials, private services, internal data, or an endorsement by UniDT Co., Ltd.

Related MCP server: bumi-mcp

Highlights

  • Natural language to PDDL workflow through plan_from_text.

  • Direct PDDL planning through generate_plan with domain_path and problem_path.

  • Configurable LLM semantic parsing with deterministic local fallback.

  • Fast Downward integration for real planner execution.

  • Generated artifacts for every run: domain.pddl, problem.pddl, sas_plan, planner log, and result.json.

  • Stable MCP tool response shape for downstream agents or clients.

  • Tests for config loading, semantic fallback, domain matching, PDDL generation, planning, validation, and MCP responses.

Demo

The project can solve the classic farmer, wolf, goat, and cabbage river-crossing puzzle.

The animation shows the end-to-end flow: natural-language input, semantic processing, template matching, PDDL generation, Fast Downward planning, and validated plan output.

Input:

A farmer must take a wolf, a goat, and a cabbage across a river.
The boat must be driven by the farmer and can carry at most one item.
If the farmer is absent, the wolf eats the goat and the goat eats the cabbage.
Plan how to move everything safely to the other side.

Output plan:

(cross-with goat left right)
(cross-alone right left)
(cross-with cabbage left right)
(cross-with goat right left)
(cross-with wolf left right)
(cross-alone right left)
(cross-with goat left right)

This is a valid 7-step solution: take the goat first, return alone, move the cabbage, bring the goat back, move the wolf, return alone, and take the goat across again.

Architecture

The code is intentionally split into focused modules:

Module

Responsibility

config

Load .env and runtime settings.

semantic

Convert natural language into a semantic planning representation.

knowledge

Match the task to a domain template.

modeling

Generate domain/problem PDDL.

planner

Build and run the Fast Downward command.

validation

Validate declared plan actions and result shape.

workflow

Orchestrate the full planning pipeline.

server

Expose MCP tools through FastMCP.

Project Layout

pddl-mcp/
├── .github/CODEOWNERS
├── .dockerignore
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── Dockerfile
├── pyproject.toml
├── server.py
├── .mcp.json
├── docs/
│   ├── assets/
│   └── releases/
├── examples/
│   └── mcp_client_quickstart.py
├── src/pddl_mcp/
│   ├── config.py
│   ├── knowledge.py
│   ├── modeling.py
│   ├── planner.py
│   ├── semantic.py
│   ├── server.py
│   ├── validation.py
│   ├── workflow.py
│   └── resources/domain_templates.json
└── tests/

Installation

git clone https://github.com/NBNBTM/pddl-mcp-server.git
cd pddl-mcp-server
python -m pip install -e ".[dev]"
cp .env.example .env

Configuration

Edit .env for your local runtime.

Minimal configuration:

OUTPUT_DIR=output
LOG_LEVEL=INFO

Real Fast Downward planning:

FAST_DOWNWARD_PATH=/absolute/path/to/fast-downward.py
FAST_DOWNWARD_SEARCH=astar(blind())
MAX_PLANNING_TIME=300

Optional LLM semantic parsing:

LLM_API_URL=https://your-llm-endpoint.example/v1/chat/completions
LLM_API_KEY=...
LLM_MODEL=qwen-max
LLM_TIMEOUT=120
LLM_RETRIES=2

LLM_API_TOKEN is also supported as a backward-compatible alias when LLM_API_KEY is empty.

Do not commit real .env files or API keys. The repository only includes .env.example.

Fast Downward Setup

One local setup option:

mkdir -p .tools
git clone https://github.com/aibasel/downward.git .tools/downward
cd .tools/downward
python build.py

Then set:

FAST_DOWNWARD_PATH=/absolute/path/to/pddl-mcp-server/.tools/downward/fast-downward.py

.tools/ is ignored by Git, so local planner builds are not uploaded.

Docker

Build the image from the repository root:

docker build -t pddl-mcp-server:4.0.1 .

The image compiles a pinned Fast Downward revision and sets FAST_DOWNWARD_PATH automatically. It runs the MCP server over stdio and does not contain API credentials or a local .env file.

Run it interactively and keep generated artifacts in a named volume:

docker run --rm -i \
  --mount type=volume,source=pddl-mcp-output,target=/app/output \
  pddl-mcp-server:4.0.1

Optional LLM settings must be passed at runtime, for example with --env LLM_API_URL, --env LLM_API_KEY, and --env LLM_MODEL. Never place real credentials in the Dockerfile or image build arguments.

Run The MCP Server

python server.py

The root server.py is a compatibility entry point. The actual implementation lives in pddl_mcp.server.

Python Usage

from pddl_mcp.workflow import plan_from_text_response

result = plan_from_text_response(
    "Move robot r1 from room1 to room3",
    {"task_id": "robot-demo"},
)

print(result["success"])
print(result["plan_content"])

River-crossing example:

from pddl_mcp.workflow import plan_from_text_response

text = """
A farmer must take a wolf, a goat, and a cabbage across a river.
The boat must be driven by the farmer and can carry at most one item.
If the farmer is absent, the wolf eats the goat and the goat eats the cabbage.
"""

result = plan_from_text_response(text, {"task_id": "farmer-river-demo"})
print(result["plan_content"])

MCP Tools

plan_from_text

plan_from_text(text: str, options: dict | None = None)

Runs the complete natural-language workflow:

text -> semantic parsing -> knowledge match -> PDDL generation -> planning -> validation

generate_plan

generate_plan(task: dict)

Supports two modes:

{
  "description": "Move robot r1 from room1 to room3"
}

or:

{
  "domain_path": "/path/to/domain.pddl",
  "problem_path": "/path/to/problem.pddl"
}

validate_config

Checks whether Fast Downward and LLM settings are configured correctly.

get_system_info

Returns server capabilities, Python version, platform, project root, and output directory.

Response Shape

Every planning response follows the same structure:

{
  "success": true,
  "task_id": "farmer-river-demo",
  "plan_content": "...",
  "explanation": "...",
  "artifacts": {
    "domain_path": "...",
    "problem_path": "...",
    "plan_path": "...",
    "log_path": "...",
    "result_path": "..."
  },
  "workflow_steps": [
    {
      "name": "planning",
      "success": true,
      "duration_sec": 0.136,
      "message": ""
    }
  ],
  "warnings": [],
  "error": ""
}

MCP Client Configuration

The repository includes .mcp.json:

{
  "mcpServers": {
    "pddl-planner": {
      "command": "python",
      "args": ["server.py"],
      "cwd": "."
    }
  }
}

For desktop MCP clients, use the absolute project path in cwd if relative paths are not supported by your client.

MCP Python client quickstart

After installing the project, run the included stdio client against the local server:

python examples/mcp_client_quickstart.py

Pass a different natural-language request with --text. The client lists the available tools, calls get_system_info, then sends the request to plan_from_text and prints the complete structured response.

Testing

python -m compileall -q src tests examples server.py
python -m pytest -q -p no:cacheprovider
python -m ruff check . --no-cache

Expected local result:

19 passed
All checks passed

If FAST_DOWNWARD_PATH is not configured, real planner execution reports a clear configuration warning. Mock workflow tests still run.

Release Notes

The current release notes are available at:

The project documentation site is available at:

Security Notes

  • Do not commit .env, API keys, model tokens, or private planner outputs.

  • Keep local Fast Downward builds under .tools/.

  • Generated outputs belong under output/.

  • Both .tools/ and output/ are ignored by Git.

License

Copyright (c) 2024 Lindsey Yang. This independently developed project is released by its copyright holder under the MIT License. See the copyright and source notice for the provenance boundary of the included planning-domain metadata.

Available Tools

4 tools
generate_planC

Plan from a task dictionary or existing domain/problem PDDL paths.

ParametersJSON Schema
NameRequiredDescriptionDefault
taskYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

C2.5/5.0
Behavior2/5

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

No annotations are present, so the description must fully explain behavioral traits. It only states the high-level purpose without disclosing whether the tool is read-only, what side effects occur, or any authentication/rate-limiting implications. It does not describe the output or error behavior.

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

Conciseness3/5

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

The description is concise at one sentence, but it sacrifices clarity for brevity. It is front-loaded with the verb, but the lack of detail means it is not appropriately sized for the tool's complexity.

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 that the tool has a nested object parameter and an output schema, the description is too sparse. It does not elaborate on what the output contains, how the task object should be structured, or the differences between the two input modes (dictionary vs paths). This leaves the agent under-informed.

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?

The sole parameter 'task' is described in the schema as an object with additionalProperties true, but the description adds that it can be a 'task dictionary' or 'existing domain/problem PDDL paths,' providing some semantic context. However, it does not clarify the structure or format of these alternatives, leaving ambiguity.

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

Purpose3/5

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

The description states 'Plan from a task dictionary or existing domain/problem PDDL paths,' which identifies the verb 'plan' and the resources (task dictionary or paths). However, it does not clearly distinguish itself from sibling tool 'plan_from_text,' which likely also generates plans. The phrase 'plan from' is ambiguous as to whether 'plan' is a noun or verb.

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 usage guidance is provided. The description does not specify when to use this tool over alternatives like 'plan_from_text' or 'validate_config,' nor does it mention prerequisites or context where this tool is appropriate.

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

get_system_infoA

Return server and runtime information.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.8/5.0
Behavior2/5

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

No annotations are provided, so the description carries full burden for behavioral disclosure. It only states a read-like operation but does not mention safety, side effects, latency, or what exactly is returned (e.g., specific metrics). Minimal 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?

The description is a single, concise sentence with no wasted words. It is front-loaded and directly conveys the tool's purpose.

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?

Given the tool has zero parameters and an output schema, the description adequately covers the high-level function. It could optionally list categories of information, but the simplicity of the tool makes the current description sufficient.

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?

The tool has no parameters, so the description does not need to add parameter information. It implicitly clarifies there are no arguments to configure.

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 uses a specific verb 'Return' and identifies the resource as 'server and runtime information', clearly stating the tool's function. It distinguishes well from sibling tools which deal with planning and configuration.

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?

No explicit guidance on when to use this tool versus alternatives. The purpose is obvious from the name, but the description does not provide context for usage or mention situations where it should not be used.

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

plan_from_textC

Plan from a natural-language task description.

ParametersJSON Schema
NameRequiredDescriptionDefault
textYes
optionsNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

C2.4/5.0
Behavior2/5

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

No annotations are provided, so the description bears full responsibility for disclosing behavior. The description does not state whether the tool is read-only, destructive, or requires authentication. It also does not describe the output 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.

Conciseness3/5

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

The description is a single sentence, making it concise. However, it is under-specified and lacks critical detail; true conciseness would include essential information without excess.

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 the tool has two parameters and an output schema, the description is incomplete. It does not explain the planning process, the nature of the output, or how to use the optional 'options' parameter.

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

Parameters1/5

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

Schema description coverage is 0%, and the description does not explain any parameter. 'text' and 'options' are not elaborated, leaving the agent to infer meaning from names alone. The description adds no value over the schema.

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 clearly states the tool's purpose: to plan from a natural-language task description. However, it does not differentiate from the sibling tool 'generate_plan', which likely has a similar purpose.

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 guidance is provided on when to use this tool versus alternatives like 'generate_plan'. There is no mention of prerequisites, context, or when not to use it.

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

validate_configA

Validate runtime configuration and report missing optional components.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.7/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 discloses that the tool validates and reports missing components, but does not elaborate on side effects, authentication needs, or what 'missing' means. Minimal but adequate.

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?

Single sentence, no wasted words. Perfectly concise and front-loaded.

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?

Given zero parameters and an output schema, the description is functional but lacks usage context and specifics about the report format. Adequate but could be more complete with guidance.

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?

There are zero parameters, so baseline is 4. The description adds no parameter details, but none are needed.

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 validates runtime configuration and reports missing optional components. It uses a specific verb-resource pair and distinguishes from sibling tools like generate_plan and get_system_info.

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 guidance is provided on when to use this tool versus alternatives. The description does not mention prerequisites, when to avoid, or comparison with siblings.

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. Dates show when Glama detected each change.

  1. 4 tool updatesv4.0.0
    • First observedgenerate_plan
    • First observedget_system_info
    • First observedplan_from_text
    • First observedvalidate_config

TDQS

B3.1/5.0
Disambiguation5/5

Each tool has a clearly distinct purpose: generate_plan uses structured input, plan_from_text uses natural language, get_system_info provides runtime info, and validate_config checks configuration. No overlap.

Naming Consistency3/5

Three tools follow a verb_noun pattern (generate_plan, get_system_info, validate_config), but plan_from_text breaks the pattern by starting with a noun, making it less predictable.

Tool Count4/5

With 4 tools, the server is slightly underpopulated but still reasonable for a specialized domain like PDDL planning. Each tool serves a clear role.

Completeness3/5

The tool set covers core planning generation and system info but lacks features like PDDL validation or plan debugging, which are notable gaps for a planning server.

Maintenance

ActivityMaintained
ResponsivenessSlow

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

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/NBNBTM/pddl-mcp-server'

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