Skip to main content

EasyTerritory MCP

ai.easyterritory/ezt-mcpVersion 0.1.0

Build, balance, realign and analyze sales/service territories; geocode, route, schedule, live map.

Status

Responds341 msAnswered our handshake without sign-in.

Registry data may be out of date

We could not refresh it, so this page shows the last copy.
Last checked
Nov 14, 2026, 13:29 UTC
Latency
341 ms
Remotes responding
1 of 1
Sign-in
API key
Hosting
Hosted outside the EU (detected)
Registry data as of
Nov 14, 2026, 22:14 UTC

Data from the official MCP Registry, checked by run.zero. How we check

Connect

Streamable HTTP
https://mcp.easyterritory.ai/Responds341 ms
No sign-in

Claude Code

claude mcp add --transport http ezt-mcp https://mcp.easyterritory.ai/ --header 'Authorization: Bearer <YOUR_TOKEN>'

Replace <YOUR_TOKEN> before running.

Claude Desktop and claude.ai

Settings > Connectors > Add custom connector
Name: ezt-mcp
Remote MCP server URL: https://mcp.easyterritory.ai/
This server expects the header Authorization.

Cursor

{
  "mcpServers": {
    "ezt-mcp": {
      "url": "https://mcp.easyterritory.ai/",
      "headers": {
        "Authorization": "Bearer <YOUR_TOKEN>"
      }
    }
  }
}

Replace <YOUR_TOKEN> before running.

VS Code

code --add-mcp '{"name":"ezt-mcp","type":"http","url":"https://mcp.easyterritory.ai/","headers":{"Authorization":"Bearer <YOUR_TOKEN>"}}'

Replace <YOUR_TOKEN> before running.

Built your own server? run.zero hosts MCP servers on European infrastructure.

Host your own MCP server on run.zero

Tools

58 tools

Tools of EasyTerritory MCP
Read-only
Idempotent
Open world
account_buildBuilds territories that follow an account column, such as rep name or territory code from CRM: each part goes to the group holding most of its accounts (conflict_policy). Adds a new alignment (TAL). Needs an ingested point_layer, grouping_field, part_layer, and tal_label. Grouping values are labels, not balance metrics. part_scope: bbox_intersect (default; parts near the accounts) or explicit with part_filter, e.g. {state_abbr: TX}; in_tal: {tal_id} keeps only that TAL's parts, not_in_tal: {tal_id} only the parts it leaves uncovered. A declared visit-frequency column needs visit_frequency_field or ignore_visit_frequency (CLARIFICATION_REQUIRED otherwise). With map_session_id the open map is the input. Returns a task; the result carries tal_id and ts_handle. analyze reports the statistics.NoNoNoNo
analyzeComputes territory statistics for one or more alignments, i.e. how balanced the territories are and how alignments compare: account counts, declared metric totals (e.g. Revenue), workload hours, balance scores, and cross-TAL comparison; hypothetical_moves previews a realign. Input: map_session_id (the open map as it is now), ts_handle, or a completed build job_id (pass tal_ids when several TALs exist). metrics: omit for every declared column, or name them; workload and account_count are always available. Workload needs dwell (dwell_time, the build's recorded dwell, or the layer's dwell_time_field); without it the result has every other statistic, no workload, and workload_omitted.ask_user to put to the user. analysis_panel=single with map_session_id fills the map dock (analysis_panel.status=pushed). Territory account_count, metric_totals, workload_total (minutes), and the dock grid cover accounts_point_layer (build point_layer), never seed, contractor, or visit layers; point_counts_by_layer counts every layer. Drive-time alignments count accounts inside each polygon. Returns a task.NoNoNoNo
analyze_network_coverageFinds coverage gaps in a contractor (vendor, service provider, technician, repair shop) network: counts the contractors that reach each demand point (customer, claim, store, ZIP center). Reads contractor_layer (ingested with layer_role=contractors) and demand_layer. coverage: {rule: drive_time, max_minutes} (straight-line travel model, no provider calls), {rule: drive_time, source: isochrone_tal, isochrone_tal_id} (isochrone_build areas around the contractors), or {rule: zip_list} (declared service ZIPs). One trade per call ('*' for all). Missing layers, coverage, or trade return CLARIFICATION_REQUIRED with the question. Writes new layers, never the source: <demand>_coverage (contractor_count, single_source, coverage_class red none / amber one / green 2+ / blue saturated, nearest contractor and minutes, capacity_ratio, gap score) and <demand>_gaps; gap_territory=true adds the all-gap ZIPs as one territory. Assigns nothing; dividing work is auto_build. Returns a task; the result has coverage_pct, gap and single-source counts, top_gaps, and per-contractor reach.NoNoNoNo
analyze_routesReturns the total hours for each of the routes calculate_route has drawn: drive hours, dwell hours, route_workload_hours (provider drive time plus dwell, no visit-frequency multiplier), stop coordinates, centroid, and bbox. Synchronous. Needs map_session_id or ts_handle, and dwell from dwell_time or the dwell recorded on the route; unresolved dwell returns CLARIFICATION_REQUIRED (needs_dwell). A circuit's stop_count includes the return to the start, so that stop's dwell counts twice. Facts only: no capacity, ranking, or overload flags. These hours are a different measure from territory and cluster workload; territory statistics come from analyze.NoYesYesNo
auto_buildPartitions ingested account points into balanced sales territories with equal workload, metric, or count over a part layer (e.g. ZIPs) as a new alignment (TAL). Needs the user's choices: build_mode (fixed_territory_count + territory_count, fixed_workload_target + target_workload hours, or scoped_split), objective (workload_bias = drive + dwell, metric_bias = one column such as Revenue, count_bias = account count; sum 100), and dwell_time (a column or a stated scalar). A missing choice returns CLARIFICATION_REQUIRED with ask_user; a visit-frequency column also needs visit_frequency_field or ignore_visit_frequency. seed_point_layer seeds territories from provider points (any count). part_scope: bbox_intersect (default; can be national) or explicit with part_filter, e.g. {state_abbr: TX}; accounts outside stay unassigned (UNASSIGNED_ACCOUNTS). part_filter {in_tal: {tal_id}} keeps a TAL's parts; {not_in_tal: {tal_id}} its white space. With map_session_id the open map is the input. Returns a task; national builds take minutes. The result carries tal_id, ts_handle, and phase_timings_ms.NoNoNoNo
calculate_routeSequences and drives a set of stops, e.g. a technician from home to the depot, then the day's calls, and back home: returns the order, road distance, drive time, per-leg timings, and geometry from TomTom or Azure Maps, and draws the path with numbered stops on the open map (map_session_id). Creates no territory and changes no assignment. route_type is the user's choice: circuit (returns to start), tour (ends at the required end stop), or open_tour (one way). stop_sets are visited in the order given and no stop moves between sets; order is optimize or as_given; group_by_field adds priority bands. Stops are inline coordinates or point-layer references (e.g. source.filter.territory_id); point_ids and stop_id are point_id values (visits: <account_id>#<n>). A new route_id adds a second route; recalculating an existing route_id replaces it, e.g. to drop a stop. dwell_time is stored for analyze_routes. Route drive time is a different measure from territory workload. No provider key returns ROUTING_NOT_CONFIGURED; past the monthly quota, PROVIDER_QUOTA_EXCEEDED. Returns a task.NoNoNoYes
cluster_pointsGroups the points of one ingested layer into balanced clusters directly, with no ZIP or part layer and no territory alignment. Writes group_field (default group_id) on every point and colors the layer by it, replacing any prior color classification (size and shape channels stay). Needs build_mode (fixed_territory_count or fixed_workload_target), objective, and dwell_time, as in auto_build; a missing one returns CLARIFICATION_REQUIRED with the question. point_filter (e.g. {STATE: FL}) clusters a subset of the layer; unmatched points stay, ungrouped. Max 25,000 points after the filter. seed_point_layer, a second point layer such as technician homes, seeds the groups: with more seeds than groups the best-placed ones are used (seed_summary.unused lists the rest), with fewer the solver adds supplemental seeds in uncovered demand. seed_attraction 0-100 (default 70) is the pull of each seed on its group. Returns a task; the result lists groups with point_count, workload_hours, and point_ids.NoNoNoNo
configure_mapUpdates map settings on the Territory Solution and refreshes the live map: project_name (map heading), theme (dark | light basemap and UI style), loaded_part_layers ([] hides ZIP/part outlines; builds never load them), active_part_layer, active_tal_id, center and zoom (default view; the live map jumps there), and point symbology. point_layer_classifications entries are {point_layer, field, method: quantile | equal_interval | categorical | manual, class_count 2-12, channel: color | size | shape, optional colors/sizes/shapes/style}; the server computes the breaks and returns per-class counts. One classification per channel per layer; clear:true removes one. Shapes cover role icons and all Designer symbols (circle, ring, square, triangle, triangle_down, diamond, star, star4, star6, star8, cross, house, pin, pin_solid, square_pin, flag, hexagon, pentagon, shield, arrow_up, building, tower, person, vehicle, gear, paint_swath, plus *_open variants). classification without point_layer is a project-level setting that does not color points. Input: map_session_id (the live map) or ts_handle.NoNoNoNo
create_territory_from_partsCreates one leaf territory from a list of part_ids (e.g. a committed map selection), in a new alignment or an existing one (tal_id). With map_session_id the live map's Territory Solution is updated and repainted; otherwise ts_handle (a new ts_handle is returned). map_session_id wins when both are passed. territory_name is a display label; the result's created_territory.territory_id is the stable id for later edits, plus leaf_territories and selection_summary (duplicate_part_ids). Dwell is optional here and is not inherited from an earlier auto_build; dwell_time is recorded for later analyze. Without it, analyze reports every statistic except workload and returns workload_omitted.ask_user. Returns a task.NoNoNoNo
delete_point_layerPoint-layer delete: removes one point layer and its account points from the Territory Solution and the open map, in one synchronous call. Needs point_layer (the layer id or its exact unique label), plus map_session_id or ts_handle. Territories, part overlays, and other point layers stay. A layer that is already gone returns ok with already_absent=true; an ambiguous label returns AMBIGUOUS_POINT_LAYER with matching_point_layers. ingest_accounts does not replace an existing layer; delete it here first. A visit layer derived from the deleted layer is reported and kept.YesNoNoNo
delete_routeRoute delete: removes one whole route from the Territory Solution and the open map, in one synchronous call. Needs route_id or the route's exact unique label, plus map_session_id or ts_handle. A route that is already gone returns ok with already_absent=true; an ambiguous label returns AMBIGUOUS_ROUTE with matching_route_ids. A single stop is removed by recalculating the same route_id with calculate_route.YesNoNoNo
delete_talDeletes one whole territory alignment (TAL: 'the territory layer', 'all territories') from the Territory Solution and the open map, in one synchronous call. Needs tal_id or the TAL's exact unique label, plus map_session_id or ts_handle. Points, part-layer overlays, and routes stay; the map switches to a remaining alignment or to points only. A TAL that is already gone returns ok with already_absent=true; an ambiguous label returns AMBIGUOUS_TAL. One territory is removed with delete_territory instead.YesNoNoNo
delete_territoryDeletes one leaf territory from an alignment; its parts become unassigned. Needs tal_id, territory_id (the leaf id or its exact unique display name), and the Territory Solution from map_session_id or ts_handle. A territory that is already gone returns ok with already_absent=true and no task; otherwise returns a task and the open map repaints. Related: territory_merge hands a leaving rep's territory to its neighbors; delete_tal removes a whole alignment in one call.YesNoNoNo
direct_buildBuilds territories from known part-to-territory assignments (a ZIP-to-territory sheet or file, including a three-level region/district/territory hierarchy via territory_path) and adds them to the Territory Solution as a new alignment (TAL). Assignments come only as an assignments_handle (aup_...) from request_assignment_upload (the file, csv_text, or assignment rows). Sheets with Postal Code plus Territory/Region/Division columns are mapped automatically. Duplicate part_ids follow duplicate_part_policy (default keep_first). Returns a task; the result carries tal_id and ts_handle and paints the open map. Location points load with ingest_accounts; balanced partitions come from auto_build; grouping by a column is account_build.NoNoNoNo
discover_intentMaps a free-text territory request to a workflow. Read-only keyword routing; no compute. Returns intent_category, the recommended tool order, the main tool (tier1_tool, null when the request is ambiguous) and alternatives, required_inputs, clarifying_questions for missing inputs, and the workflow guide inline as guidance {uri, title, excerpt}. Covers building territories (auto_build, account_build, direct_build, cluster_points, seed_build), editing (realign, split, merge, rebalance), analyze, geocoding and ingest, showing a ZIP or part layer, routes, drive-time areas (isochrone_build), recurring visit schedules (schedule_visits), contractor coverage gaps (analyze_network_coverage), listing points in a territory (points_in_territory), and moving a Territory Solution to or from EasyTerritory Designer.NoYesYesNo
ensure_map_viewerReports whether the person has the map open (viewer_status.connected) for a map_session_id from get_map_visualization, waiting up to wait_seconds (max 30 s per call; the result reports requested_wait_seconds and max_wait_seconds). Works the same for the in-chat map and the map_url tab. Returns VIEWER_NOT_CONNECTED while the map is still closed; the same call can be repeated while the person opens it. Build, analyze, and selection results paint live once the viewer is connected.NoYesYesNo
ep_graph_traverseTraverses the EMEP knowledge graph from a topic file (e.g. 'workflows/realign-by-selection.md') to related guidance, up to `depth` hops. Returns no edges unless the pack ships a _graph.yaml.NoYesYesNo
ep_list_topicsLists EMEP topics grouped by type (concept, workflow, interface, troubleshooting, decision). Optional `type` filter.NoYesYesNo
ep_searchSemantic search over the EZT MCP Expert Pack (EMEP): workflow guidance, concepts, interfaces, and common mistakes. Returns ranked markdown chunks with source files; atoms pulled in via `requires` are flagged requires_expanded. Degrades to the ezt://guidance/... resources if retrieval is unavailable. Examples: 'build balanced territories from accounts', 'viewer not connected before compute', 'auto_build vs account_build'.NoYesYesNo
export_geojsonExports the territory solution as one GeoJSON file to share, archive, or open in EasyTerritory Designer: territory polygons with part_ids, points, and routes with numbered stops, each carrying its displayed style. tal_ids, point_layers, and route_layers narrow it; include_points / include_routes omit a family. Input: map_session_id, ts_handle, or a completed build job_id. Returns a task whose result is geojson_artifact, share_url (key-less browser download for one hour; give the user share_with_user), and download_url (GET with the API key), never an inline body. Both serve a plain .geojson file. import_geojson reopens the file.NoNoNoNo
extract_tal_branchExtracts one regional branch of a hierarchical alignment (by branch_rollup_territory_id or branch_territory_path) into its own Territory Solution, so a delegate can edit just that region. Returns the extract plus branch_metadata, which reintegrate_branch needs later. exclude_locked (default true) leaves locked territories out.NoNoNoNo
eztPlain-language orchestrator: takes request (the goal) and runs the matching workflow in one call, optionally with csv_file (a host file parameter), accounts_handle, assignments_handle, map_session_id, or ts_handle. An uploaded CSV is parsed, staged, and ingested onto the open map. target_hours / workload_target map to a fixed-workload auto_build. Missing build inputs (part layer, alignment name, sizing, balance, dwell) return CLARIFICATION_REQUIRED with the questions. The granular tools do the same steps individually.NoNoNoYes
geocode_addressGeocode-only pass: turns staged customer addresses into coordinates with match confidence, without loading a map layer. The rows are staged with request_account_upload (file, csv_text, or rows; up to 10,000 rows here) and passed as its upload_handle; the handle is not claimed, so ingest_accounts can load the same rows afterward. Accepts address/address_line1/street, city, state, and postal columns (common source headers are mapped). accept_suboptimal_geocodes=true accepts ZIP-centroid matches. Each address is billed once: cached no-match and suboptimal verdicts return free (failed_rows cached_verdict); a corrected address is a new lookup. Billable lookups count against a monthly per-key quota, and past it the result is PROVIDER_QUOTA_EXCEEDED with limit, used, remaining, and period_resets_at. Returns a task; the result has summary, sample_rows (10), failed_rows (first 50), a geocoded_rows_artifact with share_url for every row, and suggested_ingest. ingest_accounts alone also geocodes while it loads the map layer.NoNoNoYes
get_guidanceReturns the EZT MCP operating guide: the cross-tool workflow order and shared rules (result.text, same text as the server instructions), result.server_version, and result.seat for the caller's key (plan standard|trial, key_expires_at, and quota_remaining for geocoding, routing, and isochrone requests). Read-only. Useful at the start of a session or for a host that does not show server instructions.NoYesYesNo
get_map_selectionReturns the most recent committed selection on an open map session (map_session_id): part_layer, part_ids, and selection_task_id when the selection came from request_part_selection. Covers selections the person started from the map legend. realign takes these part_ids as moves with a leaf territory_id.NoYesYesNo
get_map_visualizationOpens the interactive territory map (Map Component) and returns map_url and map_session_id. Opens a blank map, or shows the latest state of an existing Territory Solution (e.g. yesterday's work) from ts_handle or a completed job_id. Idempotent per user_id: a second call returns the same map. new_project=true replaces the open workspace with an empty project. theme: dark | light (basemap and UI style; default dark). presentation.view_name: empty | points_only | review | selection. Apps-capable hosts render the map in chat (ui://easyterritory/map-viewer); other clients open map_url in a browser. Later map tools take map_session_id. ensure_map_viewer reports when the person has the map open.NoNoNoNo
get_part_selectionReturns the state of a map selection task (selection_task_id from request_part_selection, or active_selection_task_id in ezt://map-sessions/{id}/state): status awaiting_user_selection, committed, expired, or cancelled, and once committed the selected part_ids (with assigned and unassigned part_ids when a TAL is active). While awaiting, the response carries recommended_poll_delay_ms. Committed part_ids feed realign, create_territory_from_parts, or analyze.NoYesYesNo
import_dataverse_viewMicrosoft Copilot only (Entra sign-in): reads a Dynamics 365 account view server to server, as the signed-in user, and stages it as an account upload. No rows pass through the agent. view_id (or an exact view_name) comes from list_dataverse_views. The server adds accountid, name, and the address1 location columns to the view; they arrive as latitude, longitude, address, city, state, postal_code, country. Returns a task (follow next_action / sleep_ms, fetch the result once); the result is the same shape as an account upload: upload_handle, row_count, csv_headers, preview, upload_warnings, geocode_plan, and suggested_ingest. Confirm the column roles with the user, then ingest_accounts(**suggested_ingest.args). Limit 100,000 accounts (DATAVERSE_VIEW_TOO_LARGE). Other clients get DATAVERSE_NOT_AVAILABLE: use request_account_upload instead.NoNoNoYes
import_designer_projectOpens an EasyTerritory Designer project as a Territory Solution: the server exports it from Designer and imports it (part-based territories, non-part polygon areas such as radius buffers or hand-drawn shapes, point layers up to 250,000 features with Designer symbols/classifications, and routes). No file passes through the agent. Returns a task; the result has ts_handle and designer_warnings. With map_session_id the project replaces the open map's content. include_points / point_layers / include_routes / include_manual_polygons narrow it; part_layer forces the part layer. A Designer part layer is mapped to its EZT part layer id (listed in designer_warnings); one with no EZT match fails UNKNOWN_PART_LAYER with available_part_layers; retry with the user's choice as part_layer. Requires link_designer; project_id comes from list_designer_projects.NoNoNoYes
import_geojsonOpens a GeoJSON FeatureCollection (points, or a territory file, plain or gzip/zip) as a Territory Solution; returns ts_handle and a summary. A file of any real size moves by reference, never inline: call with no file argument for an upload_url (give the user share_with_user, or POST it with curl_example), then poll import_geojson(upload_handle) every recommended_poll_delay_ms until upload_status=received. geojson_file takes a host file (download_url). Inline geojson / geojson_text / geojson_gzip take at most 256 KB; a larger one returns INLINE_PAYLOAD_TOO_LARGE with the upload_url call to make. Polygons without part_ids import as polygon areas with tal_kind="polygon" (measured by point-in-polygon), or convert to parts with part_layer + overlay_policy="centroid_within". For a Designer project, use import_designer_project.NoNoNoYes
ingest_accountsAccount ingest: loads account rows (CRM records, a CSV, a spreadsheet) as point data on a named point layer of the Territory Solution, to add them to the map, geocoding rows without coordinates. Rows come only as accounts_handle from request_account_upload (a file, csv_text, or rows; 100,000-row cap); its suggested_ingest carries these args. latitude/lat and longitude/lon/lng pass through; other names need latitude_field/longitude_field, and unused coordinate-like columns return CLARIFICATION_REQUIRED (needs_coordinate_fields). id_field is a unique key (default row_id); duplicates return needs_unique_row_id. Only declared columns are kept: metric_fields, workload_fields, dwell_time_field, visit_frequency_field, grouping_fields, display_fields, search_fields; to load a contractor list, layer_role=contractors adds trade_field, tier_field, capacity_field, service_zip_field (analyze_network_coverage). Later use of an undeclared column returns UNDECLARED_FIELD. Over geocode quota fails it whole; a bad address bills once (fix it to retry). Returns a task with failed_rows and map_refresh.NoNoNoYes
isochrone_buildDraws the area reachable by driving from one or more origins within a time or distance budget (drive-time area, service area, catchment) and adds each area as a territory in a drive-time alignment. origins: inline {latitude, longitude} or a point-layer reference. bands: [{time_budget_seconds} or {distance_budget_meters}], one unit per call (MIXED_BUDGET_TYPES otherwise); one band gives one area per origin, several give nested areas. Limits: 25 origins, 5 bands, 6 hours, 500 km; travel_mode car or truck; depart_at supported. Areas are the provider polygons and may overlap; analyze counts accounts in every area containing them. realign/split/merge/rebalance return ISOCHRONE_TAL_NOT_EDITABLE. A band budget is not territory workload or route time. No provider key returns ISOCHRONE_NOT_CONFIGURED; the full call count is checked against the monthly quota first (PROVIDER_QUOTA_EXCEEDED). Returns a task.NoNoNoYes
link_designerConnects the customer's EasyTerritory Designer account so list_designer_projects, import_designer_project, and push_to_designer can call Designer from the server. Returns status linked (designer_origin, designer_user) or waiting_for_user with a link_url and share_with_user. The user pastes their Designer agent token (ezt_pat_...) on that page; the token is never a tool argument and never appears in a result. Repeated calls report the status; recommended_poll_delay_ms is the interval. unlink=true removes the stored link.YesNoNoYes
list_dataverse_viewsMicrosoft Copilot only (Entra sign-in): lists the Dynamics 365 account views the signed-in user can read, so their accounts import without a file. Without environment_url it lists the user's environments; with one environment it goes straight to its views, with several it returns status choose_environment and an ask_user. Views carry view_id, name, kind (system | personal), and is_default; point_readiness samples active accounts for coordinates vs address-only (address rows are geocoded at ingest). Next: import_dataverse_view(environment_url, view_id). Other clients get DATAVERSE_NOT_AVAILABLE: use request_account_upload (a CSV file) or list_designer_projects instead. DATAVERSE_CONSENT_REQUIRED carries admin_consent_url for the user's Microsoft admin.NoYesYesYes
list_designer_projectsLists the EasyTerritory Designer rolodex projects the linked Designer user can read: project_id, label, description, tags, saved_at, is_mine, and layers (point data present). q filters by text, tag by rolodex tag, mine=true to the user's own. project_id is the input to import_designer_project and push_to_designer. Without a link the error is DESIGNER_NOT_LINKED (see link_designer).NoYesYesYes
list_part_layersReturns the available canonical part layers for territory construction (for example us_zips, us_counties, ca_fsa, and active country postal or administrative polygon layers), with the same metadata as ezt://part-layers: part_layer, label, description, country_codes, admin_levels, part_count, id_format, example_part_ids, capabilities, data_version, and updated_at. Optional part_layer returns detailed metadata for one layer (bbox, aliases, supported_admin1, source_name, source_vintage, id_format_notes) or UNKNOWN_PART_LAYER. Optional country_code filters by 2-letter ISO country code. Read-only.NoYesYesNo
load_analysis_panelShows a completed analyze result in the open map's analysis dock (single or compare). Needs map_session_id and the analyze task_id/job_id or the full analyze result (with tal_analyses and ts_identity; a partial object returns INVALID_REQUEST). presentation_mode: single, compare, executive, or diagnostic. dismiss=true hides the dock and keeps the statistics on the session. Changes nothing in the Territory Solution. analyze with analysis_panel=single fills the dock in the same call.NoNoNoNo
points_in_territoryLists which account points from one point layer fall inside a territory polygon or a drive-time (isochrone) area. Per territory: point_count, metric_sums (metrics, else the layer's declared metric fields), and a sample of sample_size points (default 25, max 200; 500 across all territories) with label and metric fields, or only the fields you name. Counts and sums cover every inside point. The full list is never inline: it is in points_artifact, via download_url (GET with the API key) or share_with_user (one-hour key-less link for the user). Synchronous, read-only; needs map_session_id or ts_handle. territory_id names one leaf (id or unique display name), territory_ids several; omit both for every leaf in the TAL (tal_id, else the active or sole TAL). point_layer defaults to the sole layer with points; point_filter (e.g. {tier: 'Gold'}) filters before counting. A point counts in every containing polygon; overlaps lists shared points. Unknown ids return UNKNOWN_TAL_ID / UNKNOWN_TERRITORY_ID / UNKNOWN_POINT_LAYER with the available values.NoYesYesNo
publish_to_dataverseMicrosoft Copilot (Entra sign-in): writes stamped point-layer columns back to Dynamics 365 account records keyed by accountid (1:1 Account PATCH). Needs map_session_id or ts_handle. Point layers carry derived stamps from builds/realign (part_id, territory_id, territory_label), calculate_route (route_id, route_label, stop_sequence), schedule_visits (schedule_id, visit_count, schedule_days, schedule_dates, contractor_id, contractor_label), isochrone_build (isochrone_tal_id, isochrone_ids, isochrone_labels, isochrone_count), and cluster_points (group_id, group_label). A <point_layer>_visits layer resolves to its 1:1 parent account layer and maps schedule_day/date to schedule_days/dates. field_map maps point columns to Dynamics account logical attributes (primitive columns or territoryid / ownerid lookups resolved by name or GUID). With confirm=false (default) or no field_map, runs a read-only preflight returning status=confirmation_required, stamped_columns, candidate_target_attributes, preview_updates, and ask_user. With confirm=true, queues the batch PATCH task.YesNoNoYes
push_to_designerSaves a Territory Solution in EasyTerritory Designer from the server. Without project_id it creates a new rolodex project named label (the user's choice; a missing label returns CLARIFICATION_REQUIRED). With project_id it overwrites that project's territories, points, and routes in place. Input: map_session_id, ts_handle, or a completed build job_id. Returns a task; the result has project_id, url, and share_with_user. part_layer_id binds the Designer catalog layer (default: the layer a pulled TAL came from); tal_id picks the alignment; include_points=false sends territories and routes only. Route stops link to point layers by point_id. run_plugin / push_power_bi (default false) run the project's post-save plugin / refresh Power BI. Requires link_designer.YesNoNoYes
query_partsReturns attributes (no geometry) for parts of a part layer listed by list_part_layers or ezt://part-layers. Takes exactly one of filter (e.g. {state_abbr: TX}) or part_ids; neither or both returns INVALID_REQUEST. Paged with page_token. TAL membership (each needs map_session_id or ts_handle inside): filter.in_tal {tal_id, territory_ids?} keeps only the parts that TAL assigns (its whole footprint, however many separate regions; territory_ids narrows to those territories and everything under them); filter.not_in_tal {tal_id} drops that TAL's parts (white space), e.g. {state_abbr: TX, not_in_tal: {...}}. Both AND with other predicates. total_count is the set size. Build from it with the same part_filter.NoYesYesNo
realignMoves ZIPs or other parts (typed ids or ones selected on the map) from one territory into another within one alignment (tal_id): a ZIP move. moves=[{part_id, to_territory_id}], or realign_operation with part_ids. The Territory Solution comes from map_session_id (the open map) or ts_handle; expected_revision adds optimistic concurrency (STALE_TS_REVISION when the map changed). to_territory_id is a leaf territory_id or that leaf's exact, unique display name; an unknown or ambiguous value returns UNKNOWN_TERRITORY_ID or AMBIGUOUS_TERRITORY with available_leaf_territories. A committed map selection is read with get_map_selection; request_part_selection lets the person pick parts on the map. remove_empty_territories drops leaves left with no parts. Returns a task; the open map repaints. analyze refreshes statistics when the map has account points.YesNoNoNo
reintegrate_branchMerges an edited branch (proposal Territory Solution from extract_tal_branch) back into the master. Needs branch_metadata and expected_master_revision; returns STALE_TS_REVISION when the master changed since the extract, in which case a fresh extract is needed. Merges apply one at a time.YesNoNoNo
request_account_uploadThe one way account or address rows enter the server: stages them for ingest_accounts (accounts_handle) or geocode_address (upload_handle) and returns upload_handle, csv_headers, and suggested_ingest args with a geocode_plan. Ways in: the returned upload_url (no API key; valid up to 1 hour), which the user opens in a browser to drop a CSV or .xlsx (result.share_with_user; the path for a file the client cannot read, e.g. a SharePoint link) or a shell POSTs to (curl_example); csv_file (a host file parameter); csv_text (raw CSV, up to 25 MB per call); or rows chunks appended with upload_handle. A call with only upload_handle polls: upload_status waiting_for_file (sleep recommended_poll_delay_ms) or received, with preview (sample rows, column profile) and upload_warnings whose ask_user goes to the user before ingest. A local path in csv_file returns UNREADABLE_FILE_REFERENCE; an expired URL returns UPLOAD_TOKEN_EXPIRED and a call with upload_handle issues a new one. One handle holds at most 100,000 rows and is single-use, claimed by ingest_accounts, for 1 hour.NoNoNoNo
request_assignment_uploadThe one way part-to-territory assignment rows (e.g. a ZIP-to-territory spreadsheet with Postal Code plus Territory/Region/Division) enter the server: stages them for direct_build (assignments_handle) and returns upload_handle. Same ways in as request_account_upload: upload_url (no API key; up to 1 hour; the user opens it in a browser to drop a CSV or .xlsx, or a shell POSTs the file), csv_file, csv_text (newlines preserved), or assignment chunks appended with upload_handle; poll with only upload_handle until upload_status is received. Legacy columns map to part_id and territory_path automatically. A file of locations rather than assignments is redirected to request_account_upload. The handle is single-use and expires after 1 hour by default.NoNoNoNo
request_part_selectionLets the person adjust boundaries by picking parts (e.g. ZIPs) on the map: puts the open map into select mode on a part_layer, for purpose realign, a new territory, or a plain list. Returns selection_task_id; get_part_selection reports status (awaiting_user_selection, then committed, expired, or cancelled) and the committed part_ids, and its response carries recommended_poll_delay_ms. The commit happens on the map, not in chat. destination_territory_id and realign_operation pre-set a realign. Works on the in-chat map and the map_url tab. map_session_id selects on the open map; ts_handle opens a stored Territory Solution first. initial_part_filter opens with a set pre-selected (e.g. in_tal or white space not_in_tal) for the person to trim; build from the committed set with part_filter {selection_task_id}. A selection the person started from the map legend is read with get_map_selection.NoNoNoNo
schedule_visitsSchedules recurring visits: expands each cadence (e.g. every 7 days) across a horizon and packs visits into daily buckets under a technician-day cap. Decides which day each visit happens (auto_build and cluster_points divide accounts among people); creates no alignment. Needs point_layer (ingested with cadence declared, else UNDECLARED_FIELD), visit_frequency_field, dwell_time, and daily_capacity ({mode: not_to_exceed, hours: 8}); missing dwell or capacity returns CLARIFICATION_REQUIRED. Omitted max_buckets_per_day means one technician per day; when one does not fit, CLARIFICATION_REQUIRED carries capacity_plan. estimate_only=true returns capacity_plan. contractors (point_layer or list: start, pre_service_stops, route_type, end) anchors buckets; unanchored one-stop days warn SINGLE_STOP_DAYS. frequency_unit: interval_days or visits_per_horizon. bucket_workload_hours (drive plus dwell) is a different measure from territory workload and route_workload_hours. Returns a task. calculate_route on one bucket_id drives that day. Date limits: visit_constraints with horizon_start_date.NoNoNoNo
seed_buildGrows one territory outward from a seed {longitude, latitude} over a part layer until it holds a target: {type: location_count, value: N} or {type: metric_sum, field: <declared metric>, value: X}, counted from an ingested point layer. Adds the territory as a leaf of tal_id, or as a new alignment. Fit is closest: target_status is reached, closest_under, closest_over, frontier_exhausted, or max_parts_reached, with SEED_TARGET_UNDERSHOT/OVERSHOT warnings and the difference. Parts already in that alignment are never taken; the territory grows around them (blocked_part_count, seed_offset_km), and a seed inside an assigned part returns SEED_PART_ASSIGNED. part_scope=explicit with part_filter confines growth to an area (not_in_tal: {tal_id} keeps it out of another TAL; in_tal: {tal_id} keeps it inside one, with no tal_id so it starts a new alignment). One seed per call. An undeclared metric field returns UNDECLARED_FIELD. Returns a task with created_territory and ts_handle; the open map repaints with map_session_id.NoNoNoNo
set_map_stateChanges the open map's session state: mode, active alignment (active_tal_id), pending job reference, or camera (center [longitude, latitude] and zoom 0-24). Session only: the Territory Solution is not changed (configure_map sets a durable default view). The result's render_ack is read at publish time, so sent_unconfirmed one version behind is normal; render_ack_hint says whether to reread ezt://map-sessions/{map_session_id}/state or resend. camera reports the view in effect and its source (requested, session, map_config, or viewer_current). A set camera stays until changed; switching alignment does not refit.NoYesYesNo
show_map_overlayShows or hides something on the open map from a plain request ('add US zip codes', 'hide the zips', 'show my accounts') or overlay_kind (part_layer, point_layer, tal, route) with overlay_id. Part layers load at a zoom where they are visible (visibility.camera_action); hiding a part layer leaves territories unchanged. Point layers must already be ingested; a layer in the Territory Solution but missing from the map is re-pushed (status=refreshed, with render_ack). Point layers have no hidden state: hide wording returns HIDE_NOT_SUPPORTED with do_this_next delete_point_layer, which removes the layer; the legend checkbox hides one in a single tab. route re-shows or hides routes calculate_route drew (route_id targets one); with no route yet it returns blocked_by=needs_route. When the user named a camera, do_this_next carries the configure_map call that sets it. Input: map_session_id (preferred) or ts_handle.NoNoNoNo
submit_feedbackSends product feedback to EasyTerritory: a blocked or partial workflow, a workaround, a confusing response, or a missing capability. Returns an acknowledgement with feedback_id. Secrets, emails, Territory Solution JSON, GeoJSON, and account/CSV tables are stripped before storage; the text is meant for a description of what happened, not data.NoNoNoNo
tasks_cancelTool equivalent of the native MCP tasks/cancel, listed for clients without the Tasks capability. Requests cooperative cancellation of a task_id and returns the Task status document. Whether the Territory Solution is unchanged or partially updated follows the originating tool.YesNoNoNo
tasks_getTool equivalent of the native MCP tasks/get, listed for clients without the Tasks capability. Returns the Task status document for a task_id (holding up to wait_ms while the task is working). next_action is sleep_and_poll (wait sleep_ms, then one tasks_get), consume_result (one tasks_result call), or stop_error. status=cancelled means the user stopped it. While queued, _meta carries queue_position, queue_depth, queue_lane, and estimated_start_ms, which is advisory and not a wait time. Polling never starts work.NoYesYesNo
tasks_resultTool equivalent of the native MCP tasks/result, listed for clients without the Tasks capability. Returns the originating tool's terminal result once the task status is completed (consume_result): ts_handle, counts, timings, and map binding, never an inline Territory Solution. A build's ts_handle or task_id (as job_id) is the input analyze takes.NoYesYesNo
territory_mergeMerges a pair of adjacent territories (N to N-1 territories). By default, territory_id_b is folded into territory_id_a (or renamed to new_territory_label) and the rest of the alignment rebalances with minimal disruption, e.g. when a rep leaves and neighbors absorb the territory. Set preserve_other_territories=true for an exact two-territory union that combines only territory_id_a and territory_id_b (optionally named new_territory_label) and leaves every other territory unchanged with no rebalance. Non-adjacent ids return NON_ADJACENT_TERRITORIES. Needs source_tal_id and the Territory Solution from map_session_id or ts_handle; workload rebalance needs dwell_time (CLARIFICATION_REQUIRED otherwise). Writes a new derived alignment. Returns a task.YesNoNoNo
territory_rebalanceRebalances an existing alignment after the account data changed, keeping it as close to the current alignment as possible. Needs source_tal_id and the Territory Solution from map_session_id or ts_handle. point_layer defaults to the alignment's build layer or the only point layer; otherwise CLARIFICATION_REQUIRED (ambiguous_point_layer, with details.point_layers). Workload balance needs dwell_time; zero_workload means no account maps to a part. The current alignment is the baseline: when nothing improves the objective the result is NO_IMPROVING_REBALANCE_FOUND and nothing changes. Writes a new derived alignment. Returns a task with retention_pct and solver_diagnostics.YesNoNoNo
territory_splitTerritory split: divides one territory (e.g. an oversized one) into two while changing the rest of the alignment as little as possible (N to N+1 territories). Needs source_tal_id and target_territory_id, plus the Territory Solution from map_session_id (the open map) or ts_handle. Workload balance needs dwell_time; a missing id or dwell returns CLARIFICATION_REQUIRED with the question. Writes a new derived alignment; the source stays. Returns a task; the result carries disruption_summary (retention_pct).YesNoNoNo
workflow_advisorReturns the next tool call for a multi-step workflow, given where the workflow stands. Read-only state machine; executes nothing. intent_category: build_from_accounts | account_grouping | known_assignments | realign_existing | restructure | load_part_layer | route_stops | reachable_area | periodic_scheduling | coverage_gap_analysis | points_in_territory. state: viewer_connected, point_layer, part_layer, tal_present, analysis_fresh, plus selection/realign or restructure flags. inputs: the values known so far (part_layer, territory_count, tal_id, operation, route_type, origins, visit_frequency_field, ...); missing_inputs names the keys still needed. Returns next_tool with drafted next_args, missing_inputs (reported, never invented), blocked_by, remaining_steps, and the workflow guide inline as guidance. Order rules applied: map before compute, viewer connected before compute, ingest before build, analyze after an edit when a point layer exists. Calling it after each step with the updated state walks the whole workflow.NoYesYesNo

Details

Registry status
Active
Published
Sep 29, 2026
Updated
Sep 29, 2026
Repository
Not given
Categories (suggested)
Project managementData and analyticsSuggested categories are assigned automatically from the registry text and may be wrong. Verified operators can correct them.
GDPR
Not declared

Are you the operator? Claim this listing