Listed from the MCP registry; nobody on Odel publishes it.
NYC 311: how to report a problem, district numbers from BoardStat, the 311 calendar and alerts
Runs on your machine from its package; the steps are below.
At most: only reads or looks up information.
Odel charges nothing per call. The publisher may charge for its own service.
Runs locally over stdio
This server isn't hosted — your MCP client launches it from a package registry. Use one of the commands below, or drop the config into your client (e.g. Claude Desktop).
Run
npx -y @betanyc/nyc-311-mcp
MCP client config
{
"mcpServers": {
"nyc-311": {
"command": "npx",
"args": [
"-y",
"@betanyc/nyc-311-mcp"
]
}
}
}An MCP server that connects an AI assistant like Claude to New York City's 311 data. Ask it how to report a problem, what your community district reports most, how fast agencies close requests, or whether alternate side parking is on today. It answers from the City's own data and tells you where each answer came from.
Built by BetaNYC. Free and open source.
See every tool, with real questions and answers: betanyc.github.io/nyc-311-mcp
If this is an emergency, or if you think this is an emergency, call 911. Every answer from every tool ends with this text: "For informational purposes only. BetaNYC builds these answers from City data; they may contain errors. Check the City's 311 page before you report. If this is an emergency, or if you think this is an emergency, call 911."
Version 1.1.0 had 4 tools. Version 1.2.0 has 21.
It went through 19 beta builds before this release. The full history is in CHANGELOG.md.
You need Node.js 18 or later.
Claude Desktop. In the Claude menu, choose Settings… › Developer › Edit Config,
and add this inside mcpServers in claude_desktop_config.json:
{
"mcpServers": {
"nyc-311": {
"command": "npx",
"args": ["-y", "@betanyc/nyc-311-mcp"],
"env": { "NYC_311_API_KEY": "your_key_here" }
}
}
}
Save, quit Claude Desktop completely, and open it again. No API key? Leave out the "env"
line and the comma before it.
Claude Code. In a terminal:
claude mcp add --env NYC_311_API_KEY=your_key_here --transport stdio nyc-311 \
-- npx -y @betanyc/nyc-311-mcp
Add --scope user to use it in every project. Check it with claude mcp get nyc-311. No API
key? Leave out --env NYC_311_API_KEY=your_key_here.
Any other MCP app. Run npx -y @betanyc/nyc-311-mcp, with NYC_311_API_KEY set if you
have one.
To check it worked, ask your assistant "Which nyc-311 tools do you have?" You should see 21,
including draft_311_report. The install guide has more detail.
Already on 1.1.0? npx keeps a copy of what it downloaded. If you still see 4 tools, quit
your app, delete the _npx folder in npm's cache (~/.npm/_npx on a Mac or Linux,
%LOCALAPPDATA%\npm-cache\_npx on Windows), and open the app again.
Its data cache is about 85 MB of public City data, in ~/Library/Caches/nyc-311-mcp on a
Mac, %LOCALAPPDATA%\nyc-311-mcp\Cache on Windows, and ~/.cache/nyc-311-mcp on Linux. Set
NYC_311_MCP_CACHE_DIR to put it somewhere else.
Seven tools use the NYC 311 Public API and need a free key: the calendar, status, the two request lookups, and the three reporting-help tools. The district tools and the Local Law 47 reports work without one.
Keep the key to yourself. Never paste it into a GitHub issue.
The portal lists two other products. NYC 311 Public — High Demand gives a higher rate limit. NYC 311 Developer Partner is for creating service requests, which this server never does. You don't need either.
You don't need to know the tool names. Ask in plain English and your assistant picks the tool. The website has the same list with a replay of a real answer for each.
Tell it what's wrong in your own words. It finds the City's own 311 article for that problem, the agency that handles it, and every way to report it. It can also write a short report for you to paste in. It never files anything. You do that yourself.
how_to_report (New in 1.2.0; needs the free 311 API key). Describe the problem the way you'd tell a neighbor. It searches the City's 311 articles and gives back the best match: the article title and link on 311 Online, the agency, the 311 problem type, what the City says happens next, and every way to report it. Give it your district and it also tells you how often people there reported the same thing. If your description sounds dangerous, the first line tells you to call 911. It catches a lot, but it will miss some emergencies, so don't count on it for that.
description (required), borough, community_district, council_district, last_days, category_id, limitdraft_311_report (New in 1.2.0; needs the free 311 API key). Writes a short report you can paste into 311 Online: the problem, where, when, and what you saw. It doesn't fill in anything you didn't tell it. If something is missing, it marks the gap and asks you. It links the right 311 page, lists the City's Problem Detail options (from a 2024 City list, so they may be out of date), and says what happens after you report. It won't write a draft when it sees danger. It tells you to call 911 instead. It doesn't send anything or fill in any form.
description (required), location, borough, when, ongoing, details, include_contactlist_311_categories (New in 1.2.0; needs the free 311 API key). Browse 311's own topics, the same ones on 311 Online, when a match looks wrong or you just want to see what 311 covers. Pick a topic to list its articles, 20 at a time.
category_id, offsetThese read the files BoardStat builds every night from NYC Open Data, with 311 requests from 2020 on. Every answer links to the BoardStat page with the same district, dates and problems, so you can check the numbers yourself. No API key needed.
find_district (New in 1.2.0; no key needed). Type an address the way you normally would. It tells you the community district and the Council district, and how many 311 requests have been made there since 2020.
address (required), boroughdistrict_summary (New in 1.2.0; no key needed). The big picture for one district: how many requests, how many aren't closed, how long they take to close, and the top problems. For each top problem, it compares the district's share with the borough's and the city's.
community_district, council_district, from_date, to_date, fiscal_year, last_days, limittop_problems (New in 1.2.0; no key needed). The most-reported problems in a district for any period, next to the same days a year earlier.
community_district, council_district, from_date, to_date, fiscal_year, last_days, agency, status, limitproblem_trend (New in 1.2.0; no key needed). One problem, month by month, in one district, with the same days a year earlier next to each month.
community_district, council_district, from_date, to_date, fiscal_year, last_days, problem (required), descriptions, exclude_descriptions, agency, statusagency_response (New in 1.2.0; no key needed). For each agency: how many requests, how many are closed, and the median and average days to close. Remember that closed doesn't mean fixed.
community_district, council_district, from_date, to_date, fiscal_year, last_days, problems, descriptions, exclude_descriptions, limitstill_open (New in 1.2.0; no key needed). Requests that aren't closed yet, oldest first, with how many days each has been open and a count by agency. The City doesn't define its statuses, so we explain each one and label the explanation as ours.
community_district, council_district, from_date, to_date, fiscal_year, last_days, problems, descriptions, exclude_descriptions, agency, limittop_addresses (New in 1.2.0; no key needed). The addresses with the most requests in a district, with each one's most common problem. You can narrow it to one problem.
community_district, council_district, from_date, to_date, fiscal_year, last_days, problems, descriptions, exclude_descriptions, agency, status, limitaddress_history (New in 1.2.0; no key needed). Every request at one address since 2020, newest first, with the status explained and the agency's own resolution text. It's the closest thing to looking up a request when you don't have its number.
address (required), borough, community_district, from_date, to_date, fiscal_year, last_days, problems, status, limit, offset, data_as_offind_requests (New in 1.2.0; no key needed). Every request in a district, newest first, a page at a time. Filter by problem, agency, or status, including the City's own statuses like Pending.
community_district, council_district, from_date, to_date, fiscal_year, last_days, problems, descriptions, exclude_descriptions, agency, status, statuses, limit, offset, data_as_ofboardstat_link (New in 1.2.0; no key needed). Makes a BoardStat link with your district, dates, problem, agency, and status already set, so you can open the map and charts yourself.
community_district, council_district, from_date, to_date, fiscal_year, last_days, problems, descriptions, exclude_descriptions, agency, statusboardstat_status (New in 1.2.0; no key needed). How fresh BoardStat's data is, and whether last night's build ran late. Ask this when a number looks off.
In 2005, Local Law 47 (Gale A. Brewer) required monthly 311 reports from the City, written into Charter § 1075. Two of those reports were repealed in 2023. We rebuilt all three from NYC Open Data. They are BetaNYC rebuilds, not the City's official reports, and every answer says so. No API key needed.
ll47_service_request_report (New in 1.2.0; no key needed). Rebuilds the monthly report on requests for service, formerly Charter § 1075(b): totals by category, agency, and status, and the average and median days to close, for a month and for the fiscal year to date. Citywide, by borough, or for one district.
month, fiscal_year, community_district, council_district, borough, by_district, read_every_district, limitcb_monthly_list (New in 1.2.0; no key needed). The list that Charter § 1075(d), still law, says community boards should get: one district's requests for a month, every older request still unresolved, and the ones closed since. Comes in pages, or as a CSV.
community_district (required), month, part, data_as_of, limit, offset, formatll47_directory_assistance_report (New in 1.2.0; no key needed). Calls answered by 311 agents, by topic, for a month and the fiscal year to date, formerly Charter § 1075(c). This one is limited, and the answer says so: the open data can't separate out directory-assistance calls, and its agency column is blank. NYC Open Data can be slow here, so the first full-year answer may take a few tries.
month, fiscal_year, limitThe City's own 311 calendar and status alerts. These were in 1.1.0, too.
get_calendar (Same as 1.1.0; needs the free 311 API key). Alternate side parking, trash and recycling collection, and schools, for a day or up to 90 days.
date, from_date, to_dateget_status (Improved in 1.2.0; needs the free 311 API key). Whether Code Blue, a fire hydrant emergency, snow or ice, or an emergency management alert is in effect right now. The answer now says it in words.
type (required)Have a 311 number, like 311-12345678? These tell you where it stands, in words. The City sends a status code, and we translate it.
get_service_request (Improved in 1.2.0; needs the free 311 API key). Look up a request by its 311 number. You get the agency, the problem, the status in words, and the agency's own note about what it did. ZIP codes are removed.
sr_number (required)get_service_request_list (Improved in 1.2.0; needs the free 311 API key). Several 311 numbers at once. Any number the City can't find is listed, so nothing quietly goes missing.
sr_numbers (required)Districts. Give a community district or a Council district, not both.
BK06, MN01, "Brooklyn 6".Dates. Give one of these:
from_date and to_date, as YYYY-MM-DD. Data starts January 1, 2020.fiscal_year. It runs July 1 to June 30 and is named for the year it ends, so
2027 or "FY27" is July 1, 2026, to June 30, 2027.last_days. It counts back from the newest request in the data, not from today, because
the City publishes 311 data a few days late.With no dates, a tool uses the dates BoardStat's page opens with, about the last year.
Every district answer includes data_as_of, a boardstat_url, plain-language caveats, and
its source.
meaning_source: "BetaNYC").311-XXXXXXXX) and NYC Open Data's unique_key are different
numbers, and nothing published links them. The district tools list unique_key, which
get_service_request can't look up. Use address_history instead. Details:
docs/service-requests.md.how_to_report and draft_311_report looks for words and phrases. It
will miss some emergencies. Every answer also tells the assistant to send the person to 911
whenever anything suggests danger.Open an issue. Tell us which tool, what you asked, what you got, and what you expected. GitHub issues are public, so leave out names, phone numbers, home addresses, 311 request numbers, and your API key. A street corner or a district is enough.
get_calendarAlternate side parking, collections (trash, recycling, and compost), and schools, for one date or a range of up to 90 days. With no dates, it gives today. Dates are New York time.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
date | string | no | today | One date, YYYY-MM-DD |
from_date | string | no | — | Range start, YYYY-MM-DD |
to_date | string | no | — | Range end, YYYY-MM-DD |
A normal weekday:
{
"days": [
{
"today_id": "20261109",
"items": [
{ "type": "Alternate Side Parking", "status": "IN EFFECT", "details": "Alternate side parking and meters are in effect." },
{ "type": "Collections", "status": "ON SCHEDULE", "details": "Trash, recycling, and compost collections are on schedule." },
{ "type": "Schools", "status": "OPEN", "details": "Public schools are open." }
]
}
]
}
On a holiday, each item also has an exceptionName. A Memorial Day lookup returns
"status": "SUSPENDED" with "exceptionName": "Memorial Day 2026".
get_statusWhether one City status is in effect right now. You get the API's own answer (inEffect, and
eventName for OEM) plus a plain_language block that says yes or no in words and when it was
asked. It isn't alternate side parking. Use get_calendar for that.
type value | The City's description, from the 311 API portal (read 2026-11-08) |
|---|---|
CodeBlue | "API to determine if Code Blue status is currently active" |
FireHydrant | "API to determine if Fire Hydrant emergency is currently active" |
OEM | "API to get OEM event currently active" |
SnowOnSidewalk | "API to determine if Snow or Ice on Sidewalk emergency is currently active" |
SnowOnStreet | "API to determine if Snow or Ice on Street emergency is currently active" |
get_service_requestOne request by its 311 number (sr_number, as 311-XXXXXXXX). You get the API's fields with
ZIP codes removed: agency, problem, problem details, status code, when it was submitted, the
address, and the agency's resolution text. Since 1.2.0, a plain_language block adds the
status in words (the API sends a code, 614110003 means Closed) and the address to give
address_history.
get_service_request_listSeveral requests at once (sr_numbers, a list). Each comes back as in get_service_request.
The City leaves out a number it can't find without saying so, so since 1.2.0 they are listed
in not_found.
git clone https://github.com/BetaNYC/nyc-311-mcp.git
cd nyc-311-mcp
npm install
npm run build
NYC_311_API_KEY=your_key npm start
Run the tests (they build first and need no API key or network):
npm test
ll47_service_request_report, and cb_monthly_list read the
files BoardStat publishes every night from NYC Open
Data's 311 Service Requests dataset. Only
www.beta.nyc is contacted.ll47_directory_assistance_report reads NYC Open Data's 311 Call Center Inquiry dataset
(wewp-mm3p), one month at a time, and saves what it reads. Set SOCRATA_APP_TOKEN if you
have one. It works without one.draft_311_report reads NYC Open Data's
311 Service Level Agreements for Problem Detail
options. The City last updated that list on March 5, 2024.Rate limits on the 311 API depend on your subscription, not on this server.
This is an independent, community-built project. It is not affiliated with, endorsed by, or an official product of the City of New York.
The site at betanyc.github.io/nyc-311-mcp is built by
GitHub Pages from the docs/ folder. docs/index.html and docs/tools.html are plain HTML.
Their demos are real answers, shortened, and every line shown is copied word for
word from the tool's answer. The Markdown pages in docs/ share docs/_layouts/default.html.
Pushing a tag vX.Y.Z that matches the version in package.json runs
.github/workflows/release.yml. It runs the tests, publishes @betanyc/nyc-311-mcp to npm
with provenance, and creates a GitHub Release. Version history is in
CHANGELOG.md. Publishing needs the NPM_TOKEN repository secret.
When the Release workflow succeeds, .github/workflows/publish-mcp.yml lists the new version
in the official MCP Registry as
io.github.BetaNYC/nyc-311-mcp, from server.json. Keep server.json at the same version
as package.json; the Release workflow checks.
We maintain a set of free MCP servers for NYC and New York State civic data. The full directory, with install steps for each, is at beta.nyc/ai-tools.
For questions across all of NYC Open Data, including the full 311 dataset, try socrata-mcp-server, a third-party MCP by Nathan Storey.
BetaNYC is New York's civic technology and open data community. We work to improve lives in New York through civic design, technology, and data.
Come do civic tech with us. We run NYC School of Data, CityCamp NYC, and events all year. See what's coming up on our events calendar.
If you build something with this, we'd love to hear about it, and we can help other New Yorkers find it. Subscribe to our weekly newsletter, or send us a link for an upcoming issue.
Issues and pull requests are welcome at github.com/BetaNYC/nyc-311-mcp. Other BetaNYC MCPs in testing are listed on Beta MCPs.
These servers are free. Freedom isn't free. Become a Beta Builder.
MIT License
Copyright (c) 2026 BetaNYC
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.