Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,12 +86,24 @@ To connect using GitHub Copilot, configure the `mcp.json` file (see [VSCode docs
}
```

### Customizing the tools
If you'd like, you can enable or disable specific tools in the MCP server. For example, if you're only working with the orders tooling: You can start the server with just the that enabled:
`--include-tags="orders"`

If you want to keep the defaults, but disable a certain tool, you can: `--exclude-tags="destinations"`

In order to disable more than one tool you can provide a comma separated list like:
`--exclude-tags="destinations","moasics"`

By default, we have disabled download tools and the subscriptions tools, as we have found those tools don't work very well with LLMs at the moment.


## Example queries

- Does Planet have any recent imagery over Puget Sound?
- List my subscriptions
- Get my June 2025 subscriptions and cancel the ones with name Netherlands
- Create a PlanetScope subscription with the first item in my Netherlands Feature Collection.
- List my feature collections
- Order me the latest high-res imagery over the Netherlands
- Create a PlanetScope order with the first item in my Netherlands Feature Collection.

## Troubleshooting

Expand Down
11 changes: 8 additions & 3 deletions src/planet_mcp/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
is installed, this is installed as an executable named planet-mcp.
"""

# note - the mcp dev tooling (e.g. uv run fastmcp dev src/main.py)
# wants to find a server object named `mcp` (or it won't work)
import argparse
from planet_mcp.server import init

Expand All @@ -19,7 +17,12 @@ def csv(value):
# when using fastmcp inspector and other tools, we handle
# extra args here (or else the parser barfs)
parser.add_argument("args", nargs="*")
parser.add_argument("--include-tags", type=csv, default=None)
# default enable all tools, except download and subscriptions
parser.add_argument(
"--include-tags",
type=csv,
default={"data", "tiles", "orders", "destinations", "mosaics", "features"},
)
parser.add_argument("--exclude-tags", type=csv, default=None)
parser.add_argument("--servers", type=csv, default=None)
# similar to extra args, inspector adds this
Expand All @@ -28,6 +31,8 @@ def csv(value):


args = parse_args()
# note - the mcp dev tooling (e.g. uv run fastmcp dev src/main.py)
# wants to find a server object named `mcp` (or it won't work)
mcp = init(
enabled_servers=args.servers,
include_tags=args.include_tags,
Expand Down
32 changes: 24 additions & 8 deletions src/planet_mcp/servers/sdk.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@

from pydantic import PydanticSchemaGenerationError


# tools we don't want enabled at all.
# they simply don't work well in an AI context.
_DEFAULT_IGNORE = {
"data_wait_asset",
"orders_wait",
Expand All @@ -22,15 +25,20 @@
"destinations_patch_destination",
}

SDK_CLIENTS = [
(planet.FeaturesClient, "features"),
(planet.DataClient, "data"),
(planet.OrdersClient, "orders"),
(planet.SubscriptionsClient, "subscriptions"),
(planet.MosaicsClient, "mosaics"),
(planet.DestinationsClient, "destinations"),
]


def mcp() -> FastMCP:
mcp = FastMCP("sdk")
make_tools(mcp, planet.FeaturesClient, "features")
make_tools(mcp, planet.DataClient, "data")
make_tools(mcp, planet.OrdersClient, "orders")
make_tools(mcp, planet.SubscriptionsClient, "subscriptions")
make_tools(mcp, planet.MosaicsClient, "mosaics")
make_tools(mcp, planet.DestinationsClient, "destinations")
for client, prefix in SDK_CLIENTS:
make_tools(mcp, client, prefix)
return mcp


Expand Down Expand Up @@ -61,8 +69,16 @@ def make_tools(mcp: FastMCP, client_class: type, prefix: str):
if sig.return_annotation is None:
func = _return_wrapper(func)

if "download" in name:
opts["tags"] = set("download")
opts["tags"] = set()

for tag in ["download", "patch", "update"]:
if tag in name:
opts["tags"].add(tag)

# add tags based on sdk client
for _, tag in SDK_CLIENTS:
if tag in full_name:
opts["tags"].add(tag)

try:
mcp.tool(func, name=full_name, **opts)
Expand Down
4 changes: 2 additions & 2 deletions src/planet_mcp/servers/tiles.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
mcp = FastMCP("tiles")


@mcp.tool
@mcp.tool(tags={"tiles", "scene"})
async def get_scene_tile(
item_type: Annotated[str, Field(pattern=r"^\w+$")],
item_id: Annotated[str, Field(pattern=r"^\w+$")],
Expand Down Expand Up @@ -48,7 +48,7 @@ async def get_scene_tile(
)


@mcp.tool
@mcp.tool(tags={"tiles", "thumbnail"})
async def get_scene_thumbnail(
item_type: Annotated[str, Field(pattern=r"^\w+$")],
item_id: Annotated[str, Field(pattern=r"^\w+$")],
Expand Down