PortlandMaps (Unofficial)
Unofficial MCP server for the public PortlandMaps property/permit/zoning API. Not city-affiliated.
使うべきか
品質と安全性
検出事項(1)
- LOWquery_intersects 内
ツール定義とプロトコルへの準拠に関する自動分析に基づいています。
コンテキストコスト
これは、サーバーのツールがモデルのコンテキストに読み込まれるたびに消費されるおおよそのトークン数です。数が多いほど、ほかのタスクに使える注意が減ります。
インストール
ワンクリックインストール
これを `claude_desktop_config.json` ファイルに追加してください:
{
"mcpServers": {
"portlandmaps-mcp": {
"command": "npx",
"args": [
"portlandmaps-mcp"
]
}
}
}実行可能なパッケージ
0.2.5stdioリモートエンドポイント
https://portlandmaps-mcp.vercel.app/mcp/v2streamable-httpできること
ツール一覧
ツール(11)
🟢suggest_portlandmaps_address(query, city, county, jurisdiction, unit, ...)
1:1 wrapper for /api/suggest/. Search PortlandMaps autocomplete for addresses, intersections, landmarks, or IDs. ANSWER GUIDANCE: when this data answers a resident's zoning, permit, property, or city-code question, write for a Portland resident or small-business owner with no code, zoning, or permitting background. Lead with a 3–5 sentence plain-English summary (never open with a data table). Then cite EVERY rule, fee, number, timeline, or contact INLINE in the same sentence with both its exact code section AND a full https:// portland.gov URL (e.g. PCC 33.110.255.C, https://www.portland.gov/code/33/110/255) — never cite vaguely ("Title 33", "the BDS website") and never drop the URL. Define every acronym, add a numbered "what to do next" list, and if a number can't be cited to a specific section + URL, say so rather than stating it bare.
入力スキーマ
{
"type": "object",
"properties": {
"query": {
"type": "string",
"minLength": 1,
"description": "Search term. Can be an address, intersection, landmark name, or ID."
},
"city": {
"type": "string"
},
"county": {
"type": "string"
},
"jurisdiction": {
"type": "string"
},
"unit": {
"type": "string"
},
"units": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "number",
"const": 0
},
{
"type": "number",
"const": 1
}
]
},
"idMatches": {
"$ref": "#/properties/units",
"description": "Maps to id_matches."
},
"intersections": {
"$ref": "#/properties/units"
},
"landmarks": {
"$ref": "#/properties/units"
},
"altCoords": {
"$ref": "#/properties/units",
"description": "Maps to alt_coords."
},
"altIds": {
"$ref": "#/properties/units",
"description": "Maps to alt_ids."
},
"elements": {
"$ref": "#/properties/units"
},
"cache": {
"$ref": "#/properties/units"
},
"status": {
"type": "string",
"enum": [
"active",
"pending",
"all"
]
},
"exact": {
"$ref": "#/properties/units"
},
"ags": {
"$ref": "#/properties/units"
},
"centerline": {
"$ref": "#/properties/units"
},
"geometry": {
"anyOf": [
{
"type": "object",
"additionalProperties": {}
},
{
"type": "string"
}
]
},
"count": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 1000
},
"page": {
"type": "integer",
"exclusiveMinimum": 0
},
"extraParams": {
"type": "object",
"additionalProperties": {}
}
},
"required": [
"query"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}🟢get_portlandmaps_detail(detailType, detailId, sections, geometry, propertyId, ...)
1:1 wrapper for /api/detail/. Fetch a detail record by detail_type, detail_id, and sections. ANSWER GUIDANCE: when this data answers a resident's zoning, permit, property, or city-code question, write for a Portland resident or small-business owner with no code, zoning, or permitting background. Lead with a 3–5 sentence plain-English summary (never open with a data table). Then cite EVERY rule, fee, number, timeline, or contact INLINE in the same sentence with both its exact code section AND a full https:// portland.gov URL (e.g. PCC 33.110.255.C, https://www.portland.gov/code/33/110/255) — never cite vaguely ("Title 33", "the BDS website") and never drop the URL. Define every acronym, add a numbered "what to do next" list, and if a number can't be cited to a specific section + URL, say so rather than stating it bare.
入力スキーマ
{
"type": "object",
"properties": {
"detailType": {
"type": "string",
"minLength": 1,
"description": "Maps to detail_type."
},
"detailId": {
"type": "string",
"minLength": 1,
"description": "Maps to detail_id."
},
"sections": {
"type": "string",
"default": "*",
"description": "Use 'list' for available sections, or '*' for all sections."
},
"geometry": {
"anyOf": [
{
"type": "object",
"additionalProperties": {}
},
{
"type": "string"
}
]
},
"propertyId": {
"type": "string",
"description": "Maps to property_id."
},
"fileType": {
"type": "string",
"description": "Maps to file_type."
},
"fileId": {
"type": "string",
"description": "Maps to file_id."
},
"cacheClear": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "number",
"const": 0
},
{
"type": "number",
"const": 1
}
],
"description": "Maps to cache_clear."
},
"extraParams": {
"type": "object",
"additionalProperties": {}
}
},
"required": [
"detailType",
"detailId"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}🟢get_assessor_data(address, city, county, propertyId, stateId, ...)
1:1 wrapper for /api/assessor/. Search assessor records by address, property IDs, geometry, or assessor filters.
入力スキーマ
{
"type": "object",
"properties": {
"address": {
"type": "string"
},
"city": {
"type": "string"
},
"county": {
"type": "string",
"enum": [
"Multnomah",
"Clackamas",
"Washington"
]
},
"propertyId": {
"type": "string",
"description": "Maps to property_id."
},
"stateId": {
"type": "string",
"description": "Maps to state_id."
},
"parentStateId": {
"type": "string",
"description": "Maps to parent_state_id."
},
"zipCode": {
"type": "string",
"description": "Maps to zip_code."
},
"legalDescription": {
"type": "string",
"description": "Maps to legal_description."
},
"altAccountNumber": {
"type": "string",
"description": "Maps to alt_account_number."
},
"builtAfter": {
"type": "integer",
"description": "Maps to built_after."
},
"builtBefore": {
"type": "integer",
"description": "Maps to built_before."
},
"sqftLarger": {
"type": "number",
"description": "Maps to sqft_larger."
},
"sqftSmaller": {
"type": "number",
"description": "Maps to sqft_smaller."
},
"soldAfter": {
"type": "string",
"description": "Maps to sold_after, mm/dd/yyyy."
},
"soldBefore": {
"type": "string",
"description": "Maps to sold_before, mm/dd/yyyy."
},
"marketLarger": {
"type": "number",
"description": "Maps to market_larger."
},
"marketSmaller": {
"type": "number",
"description": "Maps to market_smaller."
},
"primary": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "number",
"const": 0
},
{
"type": "number",
"const": 1
}
]
},
"geometry": {
"anyOf": [
{
"type": "object",
"additionalProperties": {}
},
{
"type": "string"
}
]
},
"sortField": {
"type": "string",
"description": "Maps to sort_field."
},
"sortOrder": {
"type": "string",
"enum": [
"asc",
"desc"
],
"description": "Maps to sort_order."
},
"cache": {
"$ref": "#/properties/primary"
},
"count": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 1000
},
"page": {
"type": "integer",
"exclusiveMinimum": 0
},
"download": {
"$ref": "#/properties/primary"
},
"extraParams": {
"type": "object",
"additionalProperties": {}
}
},
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}🟢get_permit_data(ivrNumber, applicationNumber, address, propertyId, stateId, ...)
1:1 wrapper for /api/permit/. Search building/trade/enforcement permit records. ANSWER GUIDANCE: when this data answers a resident's zoning, permit, property, or city-code question, write for a Portland resident or small-business owner with no code, zoning, or permitting background. Lead with a 3–5 sentence plain-English summary (never open with a data table). Then cite EVERY rule, fee, number, timeline, or contact INLINE in the same sentence with both its exact code section AND a full https:// portland.gov URL (e.g. PCC 33.110.255.C, https://www.portland.gov/code/33/110/255) — never cite vaguely ("Title 33", "the BDS website") and never drop the URL. Define every acronym, add a numbered "what to do next" list, and if a number can't be cited to a specific section + URL, say so rather than stating it bare.
入力スキーマ
{
"type": "object",
"properties": {
"ivrNumber": {
"type": "integer",
"description": "Maps to ivr_number."
},
"applicationNumber": {
"type": "string",
"description": "Maps to application_number."
},
"address": {
"type": "string"
},
"propertyId": {
"type": "string",
"description": "Maps to property_id."
},
"stateId": {
"type": "string",
"description": "Maps to state_id."
},
"searchTypeId": {
"type": "integer",
"description": "Maps to search_type_id."
},
"neighborhood": {
"type": "string"
},
"neighborhoodDistrict": {
"type": "string",
"description": "Maps to neighborhood_district."
},
"businessAssociation": {
"type": "string",
"description": "Maps to business_association."
},
"county": {
"type": "string"
},
"ccbNumber": {
"type": "string",
"description": "Maps to ccb_number."
},
"dateType": {
"type": "string",
"enum": [
"issued",
"review",
"final"
],
"description": "Maps to date_type."
},
"dateFrom": {
"type": "string",
"description": "Maps to date_from, mm/dd/yyyy."
},
"dateTo": {
"type": "string",
"description": "Maps to date_to, mm/dd/yyyy."
},
"sortField": {
"type": "string",
"description": "Maps to sort_field."
},
"sortOrder": {
"type": "string",
"enum": [
"asc",
"desc"
],
"description": "Maps to sort_order."
},
"cache": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "number",
"const": 0
},
{
"type": "number",
"const": 1
}
]
},
"count": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 1000
},
"page": {
"type": "integer",
"exclusiveMinimum": 0
},
"download": {
"$ref": "#/properties/cache"
},
"extraParams": {
"type": "object",
"additionalProperties": {}
}
},
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}🟢search_landuse_cases(searchTypeId, neighborhood, neighborhoodDistrict, historicDistrict, conservationDistrict, ...)
1:1 wrapper for /api/landuse/. Search land use review cases, including Historic Resource Review and Tree Review. ANSWER GUIDANCE: when this data answers a resident's zoning, permit, property, or city-code question, write for a Portland resident or small-business owner with no code, zoning, or permitting background. Lead with a 3–5 sentence plain-English summary (never open with a data table). Then cite EVERY rule, fee, number, timeline, or contact INLINE in the same sentence with both its exact code section AND a full https:// portland.gov URL (e.g. PCC 33.110.255.C, https://www.portland.gov/code/33/110/255) — never cite vaguely ("Title 33", "the BDS website") and never drop the URL. Define every acronym, add a numbered "what to do next" list, and if a number can't be cited to a specific section + URL, say so rather than stating it bare.
入力スキーマ
{
"type": "object",
"properties": {
"searchTypeId": {
"type": "integer",
"description": "Maps to search_type_id."
},
"neighborhood": {
"type": "string"
},
"neighborhoodDistrict": {
"type": "string",
"description": "Maps to neighborhood_district."
},
"historicDistrict": {
"type": "string",
"description": "Maps to historic_district."
},
"conservationDistrict": {
"type": "string",
"description": "Maps to conservation_district."
},
"planDistrict": {
"type": "string",
"description": "Maps to plan_district."
},
"businessAssociation": {
"type": "string",
"description": "Maps to business_association."
},
"milestoneStatus": {
"type": "string",
"enum": [
"Review Complete",
"Under Review"
],
"description": "Maps to milestone_status."
},
"dateFrom": {
"type": "string",
"description": "Maps to date_from, mm/dd/yyyy."
},
"dateTo": {
"type": "string",
"description": "Maps to date_to, mm/dd/yyyy."
},
"ivrNumber": {
"type": "integer",
"description": "Maps to ivr_number."
},
"applicationNumber": {
"type": "string",
"description": "Maps to application_number."
},
"sortField": {
"type": "string",
"description": "Maps to sort_field."
},
"sortOrder": {
"type": "string",
"enum": [
"asc",
"desc"
],
"description": "Maps to sort_order."
},
"cache": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "number",
"const": 0
},
{
"type": "number",
"const": 1
}
]
},
"count": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 1000,
"default": 100
},
"page": {
"type": "integer",
"exclusiveMinimum": 0,
"default": 1
},
"download": {
"$ref": "#/properties/cache"
},
"extraParams": {
"type": "object",
"additionalProperties": {}
}
},
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}🟢search_sewer_records(type, unitId, compkey, workOrderNumber, tvInspectionNumber, ...)
1:1 wrapper for /api/sewer/. Search sewer assets, as-builts, and easements.
入力スキーマ
{
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": [
"Asset",
"AsBuilt",
"Easement"
]
},
"unitId": {
"type": "string",
"description": "Maps to unit_id."
},
"compkey": {
"type": "string"
},
"workOrderNumber": {
"type": "string",
"description": "Maps to work_order_number."
},
"tvInspectionNumber": {
"type": "string",
"description": "Maps to tv_inspection_number."
},
"serviceRequestNumber": {
"type": "string",
"description": "Maps to service_request_number."
},
"jobNumber": {
"type": "string",
"description": "Maps to job_number."
},
"jobName": {
"type": "string",
"description": "Maps to job_name."
},
"quarterSection": {
"type": "string",
"description": "Maps to quarter_section."
},
"location": {
"type": "string"
},
"comments": {
"type": "string"
},
"trackingNumber": {
"type": "string",
"description": "Maps to tracking_number."
},
"date": {
"type": "string"
},
"quitClaim": {
"type": "string",
"enum": [
"Yes",
"No"
],
"description": "Maps to quit_claim."
},
"ordinanceNumber": {
"type": "string",
"description": "Maps to ordinance_number."
},
"rightOfWay": {
"type": "string",
"description": "Maps to right_of_way."
},
"book": {
"type": "string"
},
"page": {
"type": "string",
"description": "Sewer easement page field."
},
"sortField": {
"type": "string",
"description": "Maps to sort_field."
},
"sortOrder": {
"type": "string",
"enum": [
"asc",
"desc"
],
"description": "Maps to sort_order."
},
"count": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 1000,
"default": 100
},
"pageNum": {
"type": "integer",
"exclusiveMinimum": 0,
"default": 1,
"description": "Pagination page; maps to page."
},
"download": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "number",
"const": 0
},
{
"type": "number",
"const": 1
}
]
},
"extraParams": {
"type": "object",
"additionalProperties": {}
}
},
"required": [
"type"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}🟢query_intersects(geometry, include, buffer, detail)
1:1 wrapper for /api/intersects/. Spatial intersection against named city layers such as row, taxlot, describe, street, and waterbody.
入力スキーマ
{
"type": "object",
"properties": {
"geometry": {
"type": "object",
"additionalProperties": {},
"description": "ESRI JSON geometry in wkid 2913, 3857, or 4326."
},
"include": {
"type": "array",
"items": {
"type": "string",
"enum": [
"all",
"city",
"county",
"describe",
"park",
"row",
"stream",
"street",
"taxlot",
"trail",
"waterbody",
"zipcode"
]
},
"default": [
"describe"
]
},
"buffer": {
"type": "number",
"default": 10
},
"detail": {
"type": "boolean",
"default": false
}
},
"required": [
"geometry"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}🟢convert_geometry(from, to, geometry, srid)
1:1 wrapper for /api/geometry/. Convert geometry between ESRI, WKT, GeoJSON, GPolyline, and EncodedGPolyline.
入力スキーマ
{
"type": "object",
"properties": {
"from": {
"type": "string",
"enum": [
"ESRI",
"WKT",
"GeoJSON",
"GPolyline",
"EncodedGPolyline"
]
},
"to": {
"type": "string",
"enum": [
"ESRI",
"WKT",
"GeoJSON",
"GPolyline",
"EncodedGPolyline"
]
},
"geometry": {
"type": "string",
"description": "Source geometry as a string. JSON inputs should be JSON.stringify'd."
},
"srid": {
"type": "string",
"enum": [
"2913",
"3857",
"4326"
]
}
},
"required": [
"from",
"to",
"geometry"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}🟢lookup_agol(type, id)
1:1 wrapper for /api/agol/. Retrieve City of Portland ArcGIS Online metadata, webmaps, locators, and portal info.
入力スキーマ
{
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": [
"Locators",
"Portal",
"PortalGroup",
"PortalGroupItems",
"PortalThemes",
"Webmap",
"WebmapData",
"WebmapItem",
"WebmapExtra"
]
},
"id": {
"type": "string"
}
},
"required": [
"type"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}🟢list_detail_types
Return the detail_type values accepted by get_portlandmaps_detail and the identifier each expects.
入力スキーマ
{
"type": "object",
"properties": {},
"$schema": "http://json-schema.org/draft-07/schema#"
}🟢render_parcel_shape(detailType, detailId, rings, title, includeContext, ...)
Render a property's lot as an interactive UI component (inline SVG): a City of Portland aerial photo underlay (showing the true roofline) with the parcel outline, the building footprint(s) on the lot, approximate setback dimensions, a north arrow, and faint neighbouring parcels overlaid on top. Provide a detailType+detailId to fetch geometry, or pass rings directly. Aerial, footprints, and neighbours come from Portland's public ArcGIS layers; set basemap="none" to drop the photo and includeContext=false for just the bare outline. Renders in MCP Apps hosts (Claude) and legacy mcp-ui hosts.
入力スキーマ
{
"type": "object",
"properties": {
"detailType": {
"type": "string",
"default": "zoning",
"description": "detail_type used to fetch geometry when rings are not supplied."
},
"detailId": {
"type": "string",
"description": "detail_id used to fetch geometry when rings are not supplied."
},
"rings": {
"type": "array",
"items": {
"type": "array",
"items": {
"type": "array",
"items": {
"type": "number"
}
}
},
"description": "Web Mercator (EPSG:3857) parcel rings, e.g. geometry.rings. Bypasses fetching."
},
"title": {
"type": "string",
"description": "Caption shown on the component."
},
"includeContext": {
"type": "boolean",
"default": true,
"description": "Overlay building footprints, setbacks, and neighbouring parcels. Set false for just the lot outline."
},
"basemap": {
"type": "string",
"enum": [
"aerial",
"none"
],
"default": "aerial",
"description": "Aerial photo underlay (true rooflines). 'aerial' fetches a City of Portland image; 'none' renders dark vectors only."
}
},
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}出力スキーマ
{
"type": "object",
"properties": {
"rings": {
"type": "array",
"items": {
"type": "array",
"items": {
"type": "array",
"items": {
"type": "number"
}
}
}
},
"title": {
"type": "string"
},
"areaSqFt": {
"type": "number"
},
"buildings": {
"type": "array",
"items": {
"type": "object",
"properties": {
"rings": {
"type": "array",
"items": {
"type": "array",
"items": {
"type": "array",
"items": {
"type": "number"
}
}
}
},
"onSubject": {
"type": "boolean"
},
"sqft": {
"type": "number"
},
"stories": {
"type": "number"
},
"yearBuilt": {
"type": "number"
}
},
"required": [
"rings"
],
"additionalProperties": false
}
},
"neighbors": {
"type": "array",
"items": {
"type": "array",
"items": {
"type": "array",
"items": {
"type": "array",
"items": {
"type": "number"
}
}
}
}
},
"setbacks": {
"anyOf": [
{
"type": "object",
"properties": {
"north": {
"type": "number"
},
"east": {
"type": "number"
},
"south": {
"type": "number"
},
"west": {
"type": "number"
}
},
"required": [
"north",
"east",
"south",
"west"
],
"additionalProperties": false
},
{
"type": "null"
}
]
},
"basemap": {
"anyOf": [
{
"type": "object",
"properties": {
"dataUri": {
"type": "string"
},
"attribution": {
"type": "string"
}
},
"required": [
"dataUri"
],
"additionalProperties": false
},
{
"type": "null"
}
]
}
},
"required": [
"rings",
"areaSqFt"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}コミュニティ
エビデンス