@matchuplabs/nycfhv-mcp 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +223 -14
- package/dist/lib/fhv-client.d.ts +21 -0
- package/dist/lib/fhv-client.js +25 -12
- package/dist/server-core.js +7 -2
- package/dist/tools/list-upcoming-renewals.d.ts +7 -0
- package/dist/tools/list-upcoming-renewals.js +7 -0
- package/dist/tools/subscribe-renewal-webhook.d.ts +53 -0
- package/dist/tools/subscribe-renewal-webhook.js +84 -0
- package/dist/tools/verify-tlc-vehicle.d.ts +7 -0
- package/dist/tools/verify-tlc-vehicle.js +7 -0
- package/llms-full.txt +264 -0
- package/llms.txt +25 -0
- package/package.json +20 -5
- package/server.json +5 -4
package/README.md
CHANGED
|
@@ -1,18 +1,166 @@
|
|
|
1
1
|
# @matchuplabs/nycfhv-mcp
|
|
2
2
|
|
|
3
|
-
MCP server that exposes the [NYC FHV Intelligence API](https://fhv.matchup.dev) — TLC for-hire-vehicle license verification and renewal-window lookups — as Claude
|
|
3
|
+
MCP server that exposes the [NYC FHV Intelligence API](https://fhv.matchup.dev) — real-time TLC for-hire-vehicle license verification and renewal-window lookups — as Claude, Cursor, Windsurf, and VS Code agent tools.
|
|
4
|
+
|
|
5
|
+
Data source: NYC TLC's [For-Hire Vehicles - Active dataset](https://data.cityofnewyork.us/Transportation/For-Hire-Vehicles-FHV-Active/8wbx-tsch), refreshed daily 4–7 PM ET. Public record under NY State FOIL.
|
|
6
|
+
|
|
7
|
+
## Why this exists
|
|
8
|
+
|
|
9
|
+
Apps and AI agents that touch NYC for-hire transportation today can't verify a TLC license without scraping a manual portal. This MCP wraps a commercial-grade verification API so an agent can confirm "is this vehicle currently TLC-active?" as a single tool call before authorizing a livery rate, dispatching a Medicaid NEMT trip, or pre-binding insurance.
|
|
10
|
+
|
|
11
|
+
The API also correctly handles wheelchair-accessible (WAV) status — Socrata returns the WAV column as `"WAV"` / `"PILOT"` / absent (not `"YES"` / `"NO"`), and most wrappers silently misclassify the ~8,400-vehicle WAV cohort. This one doesn't.
|
|
4
12
|
|
|
5
13
|
## Tools
|
|
6
14
|
|
|
7
15
|
| Tool | What it does | Cost |
|
|
8
16
|
|---|---|---|
|
|
9
|
-
| `verify_tlc_vehicle` | Verify an FHV by TLC license, DMV plate, or VIN.
|
|
10
|
-
| `list_upcoming_renewals` | Vehicles whose license expires in the next N days.
|
|
17
|
+
| `verify_tlc_vehicle` | Verify an FHV by TLC license, DMV plate, or VIN. | 1 credit |
|
|
18
|
+
| `list_upcoming_renewals` | Vehicles whose license expires in the next N days. | 5 credits / page |
|
|
19
|
+
| `subscribe_renewal_webhook` | Daily push notifications for renewal-window deltas. | 0 to create, 1 / event |
|
|
20
|
+
|
|
21
|
+
### `verify_tlc_vehicle`
|
|
22
|
+
|
|
23
|
+
Verify whether a NYC TLC for-hire vehicle is currently licensed. Read-only.
|
|
24
|
+
|
|
25
|
+
**Inputs**
|
|
26
|
+
|
|
27
|
+
| Param | Type | Required | Description |
|
|
28
|
+
|---|---|---|---|
|
|
29
|
+
| `identifier` | string | yes | TLC license (`C05015` or `5545596`), DMV plate (`T438350C`), or 17-char VIN. |
|
|
30
|
+
| `type` | `"auto" \| "license" \| "plate" \| "vin"` | no | Override auto-detection. Default `"auto"`. |
|
|
31
|
+
|
|
32
|
+
**Auto-detection rules**
|
|
33
|
+
|
|
34
|
+
- 17 alphanumeric chars → VIN
|
|
35
|
+
- One letter + five digits (e.g., `C05015`) → TLC license number
|
|
36
|
+
- Otherwise → DMV plate
|
|
37
|
+
|
|
38
|
+
**Example response**
|
|
39
|
+
|
|
40
|
+
```json
|
|
41
|
+
{
|
|
42
|
+
"data": {
|
|
43
|
+
"active": true,
|
|
44
|
+
"vehicle_license_number": "5545596",
|
|
45
|
+
"name": "OPERATOR NAME",
|
|
46
|
+
"license_type": "FHV",
|
|
47
|
+
"expiration_date": "2026-08-14",
|
|
48
|
+
"days_until_expiration": 95,
|
|
49
|
+
"permit_license_number": "B03404",
|
|
50
|
+
"dmv_license_plate_number": "T438350C",
|
|
51
|
+
"vehicle_vin_number": "1FADP3K20JL215555",
|
|
52
|
+
"wheelchair_accessible": false,
|
|
53
|
+
"vehicle_year": 2018,
|
|
54
|
+
"base_number": "B03404",
|
|
55
|
+
"base_name": "UBER USA, LLC",
|
|
56
|
+
"base_type": "Black Car"
|
|
57
|
+
},
|
|
58
|
+
"meta": {
|
|
59
|
+
"source": "nyc-open-data/tlc-fhv-active/8wbx-tsch",
|
|
60
|
+
"updated": "2026-05-11T22:14:00Z",
|
|
61
|
+
"credits_remaining": 4998
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
**Error shape** (any tool)
|
|
67
|
+
|
|
68
|
+
```json
|
|
69
|
+
{
|
|
70
|
+
"error": {
|
|
71
|
+
"code": "not_found",
|
|
72
|
+
"message": "No active TLC record matches that identifier.",
|
|
73
|
+
"suggested_next_step": "Confirm the identifier with the operator or try a different type."
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### `list_upcoming_renewals`
|
|
11
79
|
|
|
12
|
-
|
|
80
|
+
List vehicles whose license expires within the next N days. Read-only. Paginated.
|
|
81
|
+
|
|
82
|
+
**Inputs**
|
|
83
|
+
|
|
84
|
+
| Param | Type | Required | Description |
|
|
85
|
+
|---|---|---|---|
|
|
86
|
+
| `days` | integer (1–180) | yes | Renewal window from today, inclusive. |
|
|
87
|
+
| `base_number` | string | no | TLC base filter (e.g., `B03404` = Uber). |
|
|
88
|
+
| `wheelchair_accessible` | boolean | no | `true` = WAV only, `false` = non-WAV only, omit for both. |
|
|
89
|
+
| `vehicle_year_max` | integer | no | Max model year — fleet-aging targeting. |
|
|
90
|
+
| `page` | integer | no | 1-indexed. Default 1. |
|
|
91
|
+
| `page_size` | integer (10–100) | no | Default 50. |
|
|
92
|
+
|
|
93
|
+
**Example response**
|
|
94
|
+
|
|
95
|
+
```json
|
|
96
|
+
{
|
|
97
|
+
"data": [
|
|
98
|
+
{
|
|
99
|
+
"active": true,
|
|
100
|
+
"vehicle_license_number": "5545596",
|
|
101
|
+
"name": "OPERATOR NAME",
|
|
102
|
+
"expiration_date": "2026-06-01",
|
|
103
|
+
"days_until_expiration": 21,
|
|
104
|
+
"wheelchair_accessible": true,
|
|
105
|
+
"vehicle_year": 2017,
|
|
106
|
+
"base_number": "B03404",
|
|
107
|
+
"base_name": "UBER USA, LLC"
|
|
108
|
+
}
|
|
109
|
+
],
|
|
110
|
+
"meta": {
|
|
111
|
+
"source": "nyc-open-data/tlc-fhv-active/8wbx-tsch",
|
|
112
|
+
"updated": "2026-05-11T22:14:00Z",
|
|
113
|
+
"page": 1,
|
|
114
|
+
"page_size": 50,
|
|
115
|
+
"total_count": 412,
|
|
116
|
+
"credits_remaining": 4993
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### `subscribe_renewal_webhook`
|
|
122
|
+
|
|
123
|
+
Subscribe a webhook URL to daily renewal-window deltas. Each day after the TLC dataset refresh, the API diffs newly-entered renewal-window vehicles against yesterday's snapshot and POSTs the delta. Events are HMAC-SHA256-signed via the `signing_secret` returned at creation.
|
|
124
|
+
|
|
125
|
+
**Inputs**
|
|
126
|
+
|
|
127
|
+
| Param | Type | Required | Description |
|
|
128
|
+
|---|---|---|---|
|
|
129
|
+
| `webhook_url` | string (HTTPS) | yes | Endpoint to receive daily POST events. |
|
|
130
|
+
| `days` | integer (1–180) | no | Renewal window. Default 30. |
|
|
131
|
+
| `base_number` | string | no | Filter to one TLC base. |
|
|
132
|
+
| `wheelchair_accessible` | boolean | no | WAV-only or non-WAV-only filter. |
|
|
133
|
+
| `vehicle_year_max` | integer | no | Max model year filter. |
|
|
134
|
+
| `description` | string (≤200) | no | Human-readable label. |
|
|
135
|
+
|
|
136
|
+
**Example response**
|
|
137
|
+
|
|
138
|
+
```json
|
|
139
|
+
{
|
|
140
|
+
"data": {
|
|
141
|
+
"id": "sub_01HXYZ...",
|
|
142
|
+
"status": "active",
|
|
143
|
+
"signing_secret": "whsec_...",
|
|
144
|
+
"webhook_url": "https://example.com/fhv-webhook",
|
|
145
|
+
"filter": { "days": 30, "base_number": "B03404" },
|
|
146
|
+
"created_at": "2026-05-11T22:14:00Z"
|
|
147
|
+
},
|
|
148
|
+
"meta": {
|
|
149
|
+
"source": "matchuplabs/fhv-intelligence/subscriptions"
|
|
150
|
+
},
|
|
151
|
+
"important": "Store the signing_secret securely — it is only returned once. Use it to verify the X-FHV-Signature header on incoming webhook events."
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
## Install
|
|
13
156
|
|
|
14
157
|
1. Get an API key at [matchuplabs.com](https://matchuplabs.com) (product: `fhv-intelligence`).
|
|
15
|
-
2. Add
|
|
158
|
+
2. Add the config block below to your MCP host.
|
|
159
|
+
3. Restart the host. The three tools appear in the tool picker.
|
|
160
|
+
|
|
161
|
+
### Claude Desktop
|
|
162
|
+
|
|
163
|
+
Config path: `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows).
|
|
16
164
|
|
|
17
165
|
```json
|
|
18
166
|
{
|
|
@@ -28,20 +176,75 @@ MCP server that exposes the [NYC FHV Intelligence API](https://fhv.matchup.dev)
|
|
|
28
176
|
}
|
|
29
177
|
```
|
|
30
178
|
|
|
31
|
-
|
|
179
|
+
### Cursor
|
|
32
180
|
|
|
33
|
-
|
|
181
|
+
Config path: `~/.cursor/mcp.json` (global) or `<project>/.cursor/mcp.json` (per-project).
|
|
34
182
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
183
|
+
```json
|
|
184
|
+
{
|
|
185
|
+
"mcpServers": {
|
|
186
|
+
"nycfhv": {
|
|
187
|
+
"command": "npx",
|
|
188
|
+
"args": ["-y", "@matchuplabs/nycfhv-mcp"],
|
|
189
|
+
"env": {
|
|
190
|
+
"FHV_API_KEY": "mv_live_your_key_here"
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
```
|
|
39
196
|
|
|
40
|
-
|
|
197
|
+
### VS Code (with Copilot MCP)
|
|
41
198
|
|
|
42
|
-
|
|
199
|
+
Config path: `<project>/.vscode/mcp.json`.
|
|
200
|
+
|
|
201
|
+
```json
|
|
202
|
+
{
|
|
203
|
+
"servers": {
|
|
204
|
+
"nycfhv": {
|
|
205
|
+
"type": "stdio",
|
|
206
|
+
"command": "npx",
|
|
207
|
+
"args": ["-y", "@matchuplabs/nycfhv-mcp"],
|
|
208
|
+
"env": {
|
|
209
|
+
"FHV_API_KEY": "mv_live_your_key_here"
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
```
|
|
43
215
|
|
|
44
|
-
|
|
216
|
+
### Windsurf
|
|
217
|
+
|
|
218
|
+
Config path: `~/.codeium/windsurf/mcp_config.json`.
|
|
219
|
+
|
|
220
|
+
```json
|
|
221
|
+
{
|
|
222
|
+
"mcpServers": {
|
|
223
|
+
"nycfhv": {
|
|
224
|
+
"command": "npx",
|
|
225
|
+
"args": ["-y", "@matchuplabs/nycfhv-mcp"],
|
|
226
|
+
"env": {
|
|
227
|
+
"FHV_API_KEY": "mv_live_your_key_here"
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### Claude Code (CLI)
|
|
235
|
+
|
|
236
|
+
```bash
|
|
237
|
+
claude mcp add nycfhv -- npx -y @matchuplabs/nycfhv-mcp
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
Then set `FHV_API_KEY` in your shell or via `claude mcp` env config.
|
|
241
|
+
|
|
242
|
+
## Environment
|
|
243
|
+
|
|
244
|
+
| Variable | Required | Default |
|
|
245
|
+
|---|---|---|
|
|
246
|
+
| `FHV_API_KEY` | yes | — |
|
|
247
|
+
| `FHV_BASE_URL` | no | `https://fhv.matchup.dev` |
|
|
45
248
|
|
|
46
249
|
## Development
|
|
47
250
|
|
|
@@ -52,6 +255,12 @@ npm run build
|
|
|
52
255
|
npm test
|
|
53
256
|
```
|
|
54
257
|
|
|
258
|
+
## Links
|
|
259
|
+
|
|
260
|
+
- [API docs](https://fhv.matchup.dev)
|
|
261
|
+
- [Source (api-ventures monorepo)](https://github.com/MATCHUP-LABS/api-ventures/tree/main/products/nyc-fhv-intelligence-api/mcp-server)
|
|
262
|
+
- [Report issues](https://github.com/MATCHUP-LABS/api-ventures/issues)
|
|
263
|
+
|
|
55
264
|
## License
|
|
56
265
|
|
|
57
266
|
MIT. © Matchup Labs.
|
package/dist/lib/fhv-client.d.ts
CHANGED
|
@@ -52,4 +52,25 @@ export declare class FhvClient {
|
|
|
52
52
|
page?: number;
|
|
53
53
|
page_size?: number;
|
|
54
54
|
}): Promise<FhvResult<Vehicle[]>>;
|
|
55
|
+
/** POST /api/v1/renewals/subscriptions */
|
|
56
|
+
createSubscription(params: {
|
|
57
|
+
webhook_url: string;
|
|
58
|
+
filter: {
|
|
59
|
+
days?: number;
|
|
60
|
+
base_number?: string;
|
|
61
|
+
wheelchair_accessible?: boolean;
|
|
62
|
+
vehicle_year_max?: number;
|
|
63
|
+
};
|
|
64
|
+
description?: string;
|
|
65
|
+
}): Promise<FhvResult<Subscription>>;
|
|
66
|
+
}
|
|
67
|
+
export interface Subscription {
|
|
68
|
+
id: string;
|
|
69
|
+
webhook_url: string;
|
|
70
|
+
filter: Record<string, unknown>;
|
|
71
|
+
description?: string;
|
|
72
|
+
signing_secret: string;
|
|
73
|
+
status: "active" | "paused" | "failed";
|
|
74
|
+
created_at: string;
|
|
75
|
+
last_delivery_at: string | null;
|
|
55
76
|
}
|
package/dist/lib/fhv-client.js
CHANGED
|
@@ -53,22 +53,28 @@ export class FhvClient {
|
|
|
53
53
|
return lastResponse;
|
|
54
54
|
throw lastError ?? new Error("retryFetch exhausted retries");
|
|
55
55
|
}
|
|
56
|
-
async request(path, params = {}) {
|
|
56
|
+
async request(path, params = {}, options) {
|
|
57
|
+
const method = options?.method ?? "GET";
|
|
57
58
|
const url = new URL(path, this.baseUrl);
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
59
|
+
if (method === "GET") {
|
|
60
|
+
for (const [k, v] of Object.entries(params)) {
|
|
61
|
+
if (v !== undefined)
|
|
62
|
+
url.searchParams.set(k, String(v));
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
const headers = {
|
|
66
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
67
|
+
Accept: "application/json",
|
|
68
|
+
"User-Agent": "nycfhv-mcp/0.1.0",
|
|
69
|
+
};
|
|
70
|
+
const init = { method, headers };
|
|
71
|
+
if (options?.jsonBody !== undefined) {
|
|
72
|
+
headers["Content-Type"] = "application/json";
|
|
73
|
+
init.body = JSON.stringify(options.jsonBody);
|
|
61
74
|
}
|
|
62
75
|
let response;
|
|
63
76
|
try {
|
|
64
|
-
response = await this.retryFetch(url.toString(),
|
|
65
|
-
method: "GET",
|
|
66
|
-
headers: {
|
|
67
|
-
Authorization: `Bearer ${this.apiKey}`,
|
|
68
|
-
Accept: "application/json",
|
|
69
|
-
"User-Agent": "nycfhv-mcp/0.1.0",
|
|
70
|
-
},
|
|
71
|
-
});
|
|
77
|
+
response = await this.retryFetch(url.toString(), init);
|
|
72
78
|
}
|
|
73
79
|
catch (err) {
|
|
74
80
|
return mcpError("upstream_timeout", `Request to fhv.matchup.dev failed: ${err instanceof Error ? err.message : String(err)}`, "Check network connectivity and retry.");
|
|
@@ -94,4 +100,11 @@ export class FhvClient {
|
|
|
94
100
|
listUpcomingRenewals(params) {
|
|
95
101
|
return this.request(`/api/v1/renewals/upcoming`, params);
|
|
96
102
|
}
|
|
103
|
+
/** POST /api/v1/renewals/subscriptions */
|
|
104
|
+
createSubscription(params) {
|
|
105
|
+
return this.request(`/api/v1/renewals/subscriptions`, {}, {
|
|
106
|
+
method: "POST",
|
|
107
|
+
jsonBody: params,
|
|
108
|
+
});
|
|
109
|
+
}
|
|
97
110
|
}
|
package/dist/server-core.js
CHANGED
|
@@ -2,10 +2,11 @@ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
|
2
2
|
import { ListToolsRequestSchema, CallToolRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
|
|
3
3
|
import { TOOL_DEFINITION as verifyDef, TOOL_NAME as verifyName, verifyTlcVehicle, } from "./tools/verify-tlc-vehicle.js";
|
|
4
4
|
import { TOOL_DEFINITION as renewalsDef, TOOL_NAME as renewalsName, listUpcomingRenewals, } from "./tools/list-upcoming-renewals.js";
|
|
5
|
+
import { TOOL_DEFINITION as subscribeDef, TOOL_NAME as subscribeName, subscribeRenewalWebhook, } from "./tools/subscribe-renewal-webhook.js";
|
|
5
6
|
export function createServer() {
|
|
6
|
-
const server = new Server({ name: "nycfhv", version: "0.1.
|
|
7
|
+
const server = new Server({ name: "nycfhv", version: "0.1.1" }, { capabilities: { tools: {} } });
|
|
7
8
|
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
8
|
-
tools: [verifyDef, renewalsDef],
|
|
9
|
+
tools: [verifyDef, renewalsDef, subscribeDef],
|
|
9
10
|
}));
|
|
10
11
|
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
11
12
|
const { name, arguments: args } = request.params;
|
|
@@ -19,6 +20,10 @@ export function createServer() {
|
|
|
19
20
|
const text = await listUpcomingRenewals((args ?? {}));
|
|
20
21
|
return { content: [{ type: "text", text }] };
|
|
21
22
|
}
|
|
23
|
+
case subscribeName: {
|
|
24
|
+
const text = await subscribeRenewalWebhook((args ?? {}));
|
|
25
|
+
return { content: [{ type: "text", text }] };
|
|
26
|
+
}
|
|
22
27
|
default:
|
|
23
28
|
return {
|
|
24
29
|
content: [
|
|
@@ -2,6 +2,13 @@ export declare const TOOL_NAME = "list_upcoming_renewals";
|
|
|
2
2
|
export declare const TOOL_DEFINITION: {
|
|
3
3
|
name: string;
|
|
4
4
|
description: string;
|
|
5
|
+
annotations: {
|
|
6
|
+
title: string;
|
|
7
|
+
readOnlyHint: boolean;
|
|
8
|
+
destructiveHint: boolean;
|
|
9
|
+
idempotentHint: boolean;
|
|
10
|
+
openWorldHint: boolean;
|
|
11
|
+
};
|
|
5
12
|
inputSchema: {
|
|
6
13
|
type: "object";
|
|
7
14
|
properties: {
|
|
@@ -3,6 +3,13 @@ export const TOOL_NAME = "list_upcoming_renewals";
|
|
|
3
3
|
export const TOOL_DEFINITION = {
|
|
4
4
|
name: TOOL_NAME,
|
|
5
5
|
description: "List NYC TLC for-hire vehicles whose license expires within the next N days. Optional filters: TLC base (e.g., 'B03404' for Uber), wheelchair-accessible (WAV) only, and maximum vehicle model year (for fleet-aging targeting). Paginated, 50 results per page by default. Costs 5 credits per page. Use this for renewal-window lead lists (license expediters, insurance brokers, training schools, EV/hybrid dealer prospecting).",
|
|
6
|
+
annotations: {
|
|
7
|
+
title: "List Upcoming TLC Renewals",
|
|
8
|
+
readOnlyHint: true,
|
|
9
|
+
destructiveHint: false,
|
|
10
|
+
idempotentHint: true,
|
|
11
|
+
openWorldHint: true,
|
|
12
|
+
},
|
|
6
13
|
inputSchema: {
|
|
7
14
|
type: "object",
|
|
8
15
|
properties: {
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
export declare const TOOL_NAME = "subscribe_renewal_webhook";
|
|
2
|
+
export declare const TOOL_DEFINITION: {
|
|
3
|
+
name: string;
|
|
4
|
+
description: string;
|
|
5
|
+
annotations: {
|
|
6
|
+
title: string;
|
|
7
|
+
readOnlyHint: boolean;
|
|
8
|
+
destructiveHint: boolean;
|
|
9
|
+
idempotentHint: boolean;
|
|
10
|
+
openWorldHint: boolean;
|
|
11
|
+
};
|
|
12
|
+
inputSchema: {
|
|
13
|
+
type: "object";
|
|
14
|
+
properties: {
|
|
15
|
+
webhook_url: {
|
|
16
|
+
type: string;
|
|
17
|
+
description: string;
|
|
18
|
+
};
|
|
19
|
+
days: {
|
|
20
|
+
type: string;
|
|
21
|
+
description: string;
|
|
22
|
+
minimum: number;
|
|
23
|
+
maximum: number;
|
|
24
|
+
};
|
|
25
|
+
base_number: {
|
|
26
|
+
type: string;
|
|
27
|
+
description: string;
|
|
28
|
+
};
|
|
29
|
+
wheelchair_accessible: {
|
|
30
|
+
type: string;
|
|
31
|
+
description: string;
|
|
32
|
+
};
|
|
33
|
+
vehicle_year_max: {
|
|
34
|
+
type: string;
|
|
35
|
+
description: string;
|
|
36
|
+
};
|
|
37
|
+
description: {
|
|
38
|
+
type: string;
|
|
39
|
+
description: string;
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
required: string[];
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
export interface SubscribeRenewalWebhookArgs {
|
|
46
|
+
webhook_url: string;
|
|
47
|
+
days?: number;
|
|
48
|
+
base_number?: string;
|
|
49
|
+
wheelchair_accessible?: boolean;
|
|
50
|
+
vehicle_year_max?: number;
|
|
51
|
+
description?: string;
|
|
52
|
+
}
|
|
53
|
+
export declare function subscribeRenewalWebhook(args: SubscribeRenewalWebhookArgs): Promise<string>;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { FhvClient } from "../lib/fhv-client.js";
|
|
2
|
+
export const TOOL_NAME = "subscribe_renewal_webhook";
|
|
3
|
+
export const TOOL_DEFINITION = {
|
|
4
|
+
name: TOOL_NAME,
|
|
5
|
+
description: "Subscribe a webhook URL to daily FHV renewal-window notifications. Each day after the TLC dataset refresh (~4-7 PM ET), the API diffs newly-entered renewal-window vehicles against yesterday's snapshot and POSTs the delta to your webhook. Payload is signed with HMAC-SHA256 via the signing_secret returned at creation. Costs 0 credits to create; 1 credit per delivered event.",
|
|
6
|
+
annotations: {
|
|
7
|
+
title: "Subscribe to Renewal Webhook",
|
|
8
|
+
readOnlyHint: false,
|
|
9
|
+
destructiveHint: false,
|
|
10
|
+
idempotentHint: false,
|
|
11
|
+
openWorldHint: true,
|
|
12
|
+
},
|
|
13
|
+
inputSchema: {
|
|
14
|
+
type: "object",
|
|
15
|
+
properties: {
|
|
16
|
+
webhook_url: {
|
|
17
|
+
type: "string",
|
|
18
|
+
description: "HTTPS endpoint that will receive daily POST events with renewal-window vehicle deltas.",
|
|
19
|
+
},
|
|
20
|
+
days: {
|
|
21
|
+
type: "integer",
|
|
22
|
+
description: "Renewal window from today, 1-180 days. Vehicles entering this window trigger an event. Default 30.",
|
|
23
|
+
minimum: 1,
|
|
24
|
+
maximum: 180,
|
|
25
|
+
},
|
|
26
|
+
base_number: {
|
|
27
|
+
type: "string",
|
|
28
|
+
description: "Optional TLC base filter (e.g., 'B03404' = Uber). Only vehicles from this base trigger events.",
|
|
29
|
+
},
|
|
30
|
+
wheelchair_accessible: {
|
|
31
|
+
type: "boolean",
|
|
32
|
+
description: "If set, only WAV (true) or non-WAV (false) vehicles trigger events.",
|
|
33
|
+
},
|
|
34
|
+
vehicle_year_max: {
|
|
35
|
+
type: "integer",
|
|
36
|
+
description: "Optional max model year filter for fleet-aging targeting.",
|
|
37
|
+
},
|
|
38
|
+
description: {
|
|
39
|
+
type: "string",
|
|
40
|
+
description: "Optional human-readable label for this subscription (max 200 chars).",
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
required: ["webhook_url"],
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
export async function subscribeRenewalWebhook(args) {
|
|
47
|
+
if (!args.webhook_url || typeof args.webhook_url !== "string") {
|
|
48
|
+
return JSON.stringify({
|
|
49
|
+
error: {
|
|
50
|
+
code: "invalid_input",
|
|
51
|
+
message: "`webhook_url` is required and must be an HTTPS URL.",
|
|
52
|
+
suggested_next_step: "Provide a valid HTTPS webhook endpoint.",
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
const client = new FhvClient();
|
|
57
|
+
const result = await client.createSubscription({
|
|
58
|
+
webhook_url: args.webhook_url,
|
|
59
|
+
filter: {
|
|
60
|
+
days: args.days,
|
|
61
|
+
base_number: args.base_number,
|
|
62
|
+
wheelchair_accessible: args.wheelchair_accessible,
|
|
63
|
+
vehicle_year_max: args.vehicle_year_max,
|
|
64
|
+
},
|
|
65
|
+
description: args.description,
|
|
66
|
+
});
|
|
67
|
+
if ("error" in result) {
|
|
68
|
+
return JSON.stringify(result);
|
|
69
|
+
}
|
|
70
|
+
return JSON.stringify({
|
|
71
|
+
data: {
|
|
72
|
+
id: result.data.id,
|
|
73
|
+
status: result.data.status,
|
|
74
|
+
signing_secret: result.data.signing_secret,
|
|
75
|
+
webhook_url: result.data.webhook_url,
|
|
76
|
+
filter: result.data.filter,
|
|
77
|
+
created_at: result.data.created_at,
|
|
78
|
+
},
|
|
79
|
+
meta: {
|
|
80
|
+
source: result.meta.source,
|
|
81
|
+
},
|
|
82
|
+
important: "Store the signing_secret securely — it is only returned once. Use it to verify the X-FHV-Signature header on incoming webhook events.",
|
|
83
|
+
});
|
|
84
|
+
}
|
|
@@ -2,6 +2,13 @@ export declare const TOOL_NAME = "verify_tlc_vehicle";
|
|
|
2
2
|
export declare const TOOL_DEFINITION: {
|
|
3
3
|
name: string;
|
|
4
4
|
description: string;
|
|
5
|
+
annotations: {
|
|
6
|
+
title: string;
|
|
7
|
+
readOnlyHint: boolean;
|
|
8
|
+
destructiveHint: boolean;
|
|
9
|
+
idempotentHint: boolean;
|
|
10
|
+
openWorldHint: boolean;
|
|
11
|
+
};
|
|
5
12
|
inputSchema: {
|
|
6
13
|
type: "object";
|
|
7
14
|
properties: {
|
|
@@ -3,6 +3,13 @@ export const TOOL_NAME = "verify_tlc_vehicle";
|
|
|
3
3
|
export const TOOL_DEFINITION = {
|
|
4
4
|
name: TOOL_NAME,
|
|
5
5
|
description: "Verify whether a NYC TLC for-hire vehicle is currently licensed. Accepts a TLC license number (e.g. 'C05015' or '5545596'), DMV plate (e.g. 'T438350C'), or 17-character VIN. Returns active status, expiration date, base affiliation, wheelchair-accessible (WAV) flag, and days_until_expiration. Identifier type is auto-detected by default. Costs 1 credit per call. Use this before authorizing a livery rate, dispatch, or pre-bind insurance check on a NYC for-hire vehicle.",
|
|
6
|
+
annotations: {
|
|
7
|
+
title: "Verify TLC Vehicle",
|
|
8
|
+
readOnlyHint: true,
|
|
9
|
+
destructiveHint: false,
|
|
10
|
+
idempotentHint: true,
|
|
11
|
+
openWorldHint: true,
|
|
12
|
+
},
|
|
6
13
|
inputSchema: {
|
|
7
14
|
type: "object",
|
|
8
15
|
properties: {
|
package/llms-full.txt
ADDED
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
# @matchuplabs/nycfhv-mcp — Full Reference for LLMs
|
|
2
|
+
|
|
3
|
+
This is a single-file dump of everything an LLM needs to plan tool use against the NYC FHV Intelligence MCP server. Includes per-tool input schemas, response shapes, error semantics, and the cost model.
|
|
4
|
+
|
|
5
|
+
Package: `@matchuplabs/nycfhv-mcp` (npm)
|
|
6
|
+
Server name: `io.github.MatchupLabs/nycfhv`
|
|
7
|
+
Transport: stdio
|
|
8
|
+
Source: https://github.com/MATCHUP-LABS/api-ventures/tree/main/products/nyc-fhv-intelligence-api/mcp-server
|
|
9
|
+
|
|
10
|
+
## Environment variables
|
|
11
|
+
|
|
12
|
+
- `FHV_API_KEY` (required, secret) — get one at matchuplabs.com, product slug `fhv-intelligence`.
|
|
13
|
+
- `FHV_BASE_URL` (optional) — defaults to `https://fhv.matchup.dev`.
|
|
14
|
+
|
|
15
|
+
## Cost model
|
|
16
|
+
|
|
17
|
+
| Operation | Credits |
|
|
18
|
+
|---|---|
|
|
19
|
+
| `verify_tlc_vehicle` call | 1 |
|
|
20
|
+
| `list_upcoming_renewals` page | 5 |
|
|
21
|
+
| `subscribe_renewal_webhook` create | 0 |
|
|
22
|
+
| Webhook event delivery | 1 |
|
|
23
|
+
| Edge-cached repeat call within TTL | 0 |
|
|
24
|
+
|
|
25
|
+
Credits are charged only on successful responses. The remaining balance is in `meta.credits_remaining` on every response.
|
|
26
|
+
|
|
27
|
+
## Identifier auto-detection (verify_tlc_vehicle)
|
|
28
|
+
|
|
29
|
+
- 17 alphanumeric characters → VIN
|
|
30
|
+
- One letter followed by five digits (e.g., `C05015`) → TLC license number (legacy format)
|
|
31
|
+
- 7-digit numeric (e.g., `5545596`) → TLC license number (current format)
|
|
32
|
+
- Otherwise → DMV plate
|
|
33
|
+
|
|
34
|
+
Override via `type: "license" | "plate" | "vin"`.
|
|
35
|
+
|
|
36
|
+
## Tools
|
|
37
|
+
|
|
38
|
+
### Tool 1: verify_tlc_vehicle
|
|
39
|
+
|
|
40
|
+
Annotations: `readOnlyHint: true`, `destructiveHint: false`, `idempotentHint: true`, `openWorldHint: true`.
|
|
41
|
+
|
|
42
|
+
Description: Verify whether a NYC TLC for-hire vehicle is currently licensed. Use before authorizing a livery rate, dispatching a Medicaid NEMT trip, or pre-binding insurance.
|
|
43
|
+
|
|
44
|
+
Input schema:
|
|
45
|
+
|
|
46
|
+
```json
|
|
47
|
+
{
|
|
48
|
+
"type": "object",
|
|
49
|
+
"properties": {
|
|
50
|
+
"identifier": {
|
|
51
|
+
"type": "string",
|
|
52
|
+
"description": "TLC license number (legacy 'C05015' or 7-digit '5545596'), DMV plate, or 17-char VIN."
|
|
53
|
+
},
|
|
54
|
+
"type": {
|
|
55
|
+
"type": "string",
|
|
56
|
+
"enum": ["auto", "license", "plate", "vin"],
|
|
57
|
+
"description": "Optional override for identifier auto-detection. Default 'auto'."
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
"required": ["identifier"]
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Success response shape:
|
|
65
|
+
|
|
66
|
+
```json
|
|
67
|
+
{
|
|
68
|
+
"data": {
|
|
69
|
+
"active": "boolean",
|
|
70
|
+
"vehicle_license_number": "string",
|
|
71
|
+
"name": "string (operator name)",
|
|
72
|
+
"license_type": "string",
|
|
73
|
+
"expiration_date": "string (YYYY-MM-DD)",
|
|
74
|
+
"days_until_expiration": "number (can be negative if expired)",
|
|
75
|
+
"permit_license_number": "string | null",
|
|
76
|
+
"dmv_license_plate_number": "string | null",
|
|
77
|
+
"vehicle_vin_number": "string | null",
|
|
78
|
+
"wheelchair_accessible": "boolean",
|
|
79
|
+
"vehicle_year": "number | null",
|
|
80
|
+
"base_number": "string | null (TLC base, e.g. 'B03404')",
|
|
81
|
+
"base_name": "string | null (e.g. 'UBER USA, LLC')",
|
|
82
|
+
"base_type": "string | null (e.g. 'Black Car', 'Livery', 'Luxury Limousine')"
|
|
83
|
+
},
|
|
84
|
+
"meta": {
|
|
85
|
+
"source": "nyc-open-data/tlc-fhv-active/8wbx-tsch",
|
|
86
|
+
"updated": "ISO 8601 timestamp",
|
|
87
|
+
"credits_remaining": "number"
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Tool 2: list_upcoming_renewals
|
|
93
|
+
|
|
94
|
+
Annotations: `readOnlyHint: true`, `destructiveHint: false`, `idempotentHint: true`, `openWorldHint: true`.
|
|
95
|
+
|
|
96
|
+
Description: List vehicles whose license expires within the next N days. Paginated. Use for renewal-window lead lists (license expediters, insurance brokers, training schools, EV/hybrid dealer prospecting).
|
|
97
|
+
|
|
98
|
+
Input schema:
|
|
99
|
+
|
|
100
|
+
```json
|
|
101
|
+
{
|
|
102
|
+
"type": "object",
|
|
103
|
+
"properties": {
|
|
104
|
+
"days": {
|
|
105
|
+
"type": "integer",
|
|
106
|
+
"minimum": 1,
|
|
107
|
+
"maximum": 180,
|
|
108
|
+
"description": "Renewal window from today, inclusive. Most use cases pick 14, 30, 60, or 90."
|
|
109
|
+
},
|
|
110
|
+
"base_number": {
|
|
111
|
+
"type": "string",
|
|
112
|
+
"description": "Optional TLC base filter (case-insensitive). Example: 'B03404' = Uber, 'B00477' = Inta-Boro Acres."
|
|
113
|
+
},
|
|
114
|
+
"wheelchair_accessible": {
|
|
115
|
+
"type": "boolean",
|
|
116
|
+
"description": "true = WAV / WAV-pilot only (~8% of fleet). false = non-WAV only. Omit for both."
|
|
117
|
+
},
|
|
118
|
+
"vehicle_year_max": {
|
|
119
|
+
"type": "integer",
|
|
120
|
+
"description": "Optional max model year. Targets older fleet for replacement-financing or pre-sales lead-gen."
|
|
121
|
+
},
|
|
122
|
+
"page": {
|
|
123
|
+
"type": "integer",
|
|
124
|
+
"minimum": 1,
|
|
125
|
+
"description": "1-indexed page number. Default 1."
|
|
126
|
+
},
|
|
127
|
+
"page_size": {
|
|
128
|
+
"type": "integer",
|
|
129
|
+
"minimum": 10,
|
|
130
|
+
"maximum": 100,
|
|
131
|
+
"description": "Results per page. Default 50."
|
|
132
|
+
}
|
|
133
|
+
},
|
|
134
|
+
"required": ["days"]
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Success response shape:
|
|
139
|
+
|
|
140
|
+
```json
|
|
141
|
+
{
|
|
142
|
+
"data": "Array<Vehicle> (same shape as verify_tlc_vehicle.data, one per vehicle)",
|
|
143
|
+
"meta": {
|
|
144
|
+
"source": "nyc-open-data/tlc-fhv-active/8wbx-tsch",
|
|
145
|
+
"updated": "ISO 8601 timestamp",
|
|
146
|
+
"page": "number",
|
|
147
|
+
"page_size": "number",
|
|
148
|
+
"total_count": "number (total matching the filter, not just this page)",
|
|
149
|
+
"credits_remaining": "number"
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Tool 3: subscribe_renewal_webhook
|
|
155
|
+
|
|
156
|
+
Annotations: `readOnlyHint: false`, `destructiveHint: false`, `idempotentHint: false`, `openWorldHint: true`.
|
|
157
|
+
|
|
158
|
+
Description: Subscribe a webhook URL to daily FHV renewal-window notifications. After each daily TLC dataset refresh (~4–7 PM ET), the API diffs newly-entered renewal-window vehicles against yesterday's snapshot and POSTs the delta to the webhook. Events are HMAC-SHA256 signed via the `signing_secret` returned at creation.
|
|
159
|
+
|
|
160
|
+
Input schema:
|
|
161
|
+
|
|
162
|
+
```json
|
|
163
|
+
{
|
|
164
|
+
"type": "object",
|
|
165
|
+
"properties": {
|
|
166
|
+
"webhook_url": {
|
|
167
|
+
"type": "string",
|
|
168
|
+
"description": "HTTPS endpoint that will receive daily POST events."
|
|
169
|
+
},
|
|
170
|
+
"days": {
|
|
171
|
+
"type": "integer",
|
|
172
|
+
"minimum": 1,
|
|
173
|
+
"maximum": 180,
|
|
174
|
+
"description": "Renewal window from today. Default 30."
|
|
175
|
+
},
|
|
176
|
+
"base_number": {
|
|
177
|
+
"type": "string",
|
|
178
|
+
"description": "Optional TLC base filter."
|
|
179
|
+
},
|
|
180
|
+
"wheelchair_accessible": {
|
|
181
|
+
"type": "boolean",
|
|
182
|
+
"description": "WAV-only (true) or non-WAV-only (false) filter."
|
|
183
|
+
},
|
|
184
|
+
"vehicle_year_max": {
|
|
185
|
+
"type": "integer",
|
|
186
|
+
"description": "Max model year filter."
|
|
187
|
+
},
|
|
188
|
+
"description": {
|
|
189
|
+
"type": "string",
|
|
190
|
+
"description": "Optional human-readable label, max 200 chars."
|
|
191
|
+
}
|
|
192
|
+
},
|
|
193
|
+
"required": ["webhook_url"]
|
|
194
|
+
}
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
Success response shape:
|
|
198
|
+
|
|
199
|
+
```json
|
|
200
|
+
{
|
|
201
|
+
"data": {
|
|
202
|
+
"id": "string (subscription id)",
|
|
203
|
+
"status": "active | paused | failed",
|
|
204
|
+
"signing_secret": "string (ONLY RETURNED ONCE — store securely)",
|
|
205
|
+
"webhook_url": "string",
|
|
206
|
+
"filter": "object (echo of input filter params)",
|
|
207
|
+
"created_at": "ISO 8601 timestamp"
|
|
208
|
+
},
|
|
209
|
+
"meta": {
|
|
210
|
+
"source": "matchuplabs/fhv-intelligence/subscriptions"
|
|
211
|
+
},
|
|
212
|
+
"important": "Store the signing_secret securely — it is only returned once. Use it to verify the X-FHV-Signature header on incoming webhook events."
|
|
213
|
+
}
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
Webhook event payload (delivered daily to the registered URL):
|
|
217
|
+
|
|
218
|
+
```json
|
|
219
|
+
{
|
|
220
|
+
"event": "renewal_window.delta",
|
|
221
|
+
"subscription_id": "sub_...",
|
|
222
|
+
"delivered_at": "ISO 8601",
|
|
223
|
+
"data": {
|
|
224
|
+
"added": "Array<Vehicle>",
|
|
225
|
+
"removed": "Array<Vehicle>"
|
|
226
|
+
},
|
|
227
|
+
"meta": {
|
|
228
|
+
"source": "nyc-open-data/tlc-fhv-active/8wbx-tsch",
|
|
229
|
+
"snapshot_date": "YYYY-MM-DD"
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
Signature header: `X-FHV-Signature: sha256=<hex digest of body using signing_secret>`.
|
|
235
|
+
|
|
236
|
+
## Error semantics (all tools)
|
|
237
|
+
|
|
238
|
+
Every error follows this shape:
|
|
239
|
+
|
|
240
|
+
```json
|
|
241
|
+
{
|
|
242
|
+
"error": {
|
|
243
|
+
"code": "string (machine-readable: 'invalid_input' | 'not_found' | 'auth_failed' | 'rate_limited' | 'credits_exhausted' | 'upstream_unavailable' | 'internal_error')",
|
|
244
|
+
"message": "string (human-readable)",
|
|
245
|
+
"suggested_next_step": "string (actionable guidance for the agent)"
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
Common codes:
|
|
251
|
+
|
|
252
|
+
- `invalid_input` — bad/missing param. Re-check input schema.
|
|
253
|
+
- `not_found` — verify_tlc_vehicle: no matching active record. Vehicle may be inactive, mistyped, or never licensed.
|
|
254
|
+
- `auth_failed` — bad/missing FHV_API_KEY.
|
|
255
|
+
- `rate_limited` — too many requests for the current tier. Back off.
|
|
256
|
+
- `credits_exhausted` — out of credits. Upgrade tier or wait for monthly reset.
|
|
257
|
+
- `upstream_unavailable` — NYC Socrata is down or refreshing. Retry in 5–10 min.
|
|
258
|
+
|
|
259
|
+
## Use-case primers
|
|
260
|
+
|
|
261
|
+
- **NEMT Medicaid trip dispatch**: before assigning a trip, call `verify_tlc_vehicle` with the assigned vehicle's plate or TLC number. Confirm `active: true` and (for WAV-required trips) `wheelchair_accessible: true`. If false, route the trip to a different vehicle.
|
|
262
|
+
- **Livery insurance pre-bind**: call `verify_tlc_vehicle`; deny binding if `active: false` or `days_until_expiration < 7`.
|
|
263
|
+
- **Renewal-window lead-gen**: call `list_upcoming_renewals` with `days: 30`, optionally filtered by base or `vehicle_year_max` (for replacement-financing pitches). Paginate.
|
|
264
|
+
- **Fleet monitoring**: call `subscribe_renewal_webhook` once with your base filter; receive a daily delta of vehicles entering the renewal window without polling.
|
package/llms.txt
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# @matchuplabs/nycfhv-mcp
|
|
2
|
+
|
|
3
|
+
> MCP server for the NYC FHV Intelligence API. Verifies NYC TLC for-hire vehicle licenses (by TLC number, DMV plate, or VIN) and lists renewal-window leads. Backed by fhv.matchup.dev, daily-refreshed from NYC TLC's official For-Hire Vehicles - Active dataset (8wbx-tsch). Public-record data under NY State FOIL.
|
|
4
|
+
|
|
5
|
+
The MCP exposes 3 tools:
|
|
6
|
+
|
|
7
|
+
- `verify_tlc_vehicle` — read-only, 1 credit. Verify whether a vehicle is currently TLC-active by license, plate, or VIN. Returns active status, expiration, base affiliation, and wheelchair-accessible (WAV) flag.
|
|
8
|
+
- `list_upcoming_renewals` — read-only, 5 credits/page. Paginated list of vehicles whose license expires in the next N days. Filterable by base, WAV status, and vehicle model year.
|
|
9
|
+
- `subscribe_renewal_webhook` — write, 0 credits to create + 1 credit per delivered event. Subscribes a webhook URL to daily renewal-window deltas, HMAC-SHA256 signed.
|
|
10
|
+
|
|
11
|
+
Use cases: NEMT fleet pre-dispatch verification, livery dispatch authorization, insurance pre-bind, fleet-aging targeting for dealer/financing lead-gen, license-expediter prospecting.
|
|
12
|
+
|
|
13
|
+
## Install
|
|
14
|
+
|
|
15
|
+
- [README](https://github.com/MATCHUP-LABS/api-ventures/blob/main/products/nyc-fhv-intelligence-api/mcp-server/README.md): full install configs for Claude Desktop, Cursor, VS Code, Windsurf, Claude Code CLI.
|
|
16
|
+
- [Full schemas](https://github.com/MATCHUP-LABS/api-ventures/blob/main/products/nyc-fhv-intelligence-api/mcp-server/llms-full.txt): single-file dump of every tool definition + response shape.
|
|
17
|
+
|
|
18
|
+
## Get an API key
|
|
19
|
+
|
|
20
|
+
- [matchuplabs.com](https://matchuplabs.com) — product slug `fhv-intelligence`. Free tier available.
|
|
21
|
+
|
|
22
|
+
## Optional
|
|
23
|
+
|
|
24
|
+
- [API docs](https://fhv.matchup.dev): underlying HTTP API the MCP wraps.
|
|
25
|
+
- [Source](https://github.com/MATCHUP-LABS/api-ventures/tree/main/products/nyc-fhv-intelligence-api/mcp-server): TypeScript, MIT license.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@matchuplabs/nycfhv-mcp",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "MCP server for the NYC FHV Intelligence API. Exposes TLC for-hire vehicle license verification and renewal-window lookups as agent tools backed by fhv.matchup.dev.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -11,10 +11,16 @@
|
|
|
11
11
|
"license": "MIT",
|
|
12
12
|
"repository": {
|
|
13
13
|
"type": "git",
|
|
14
|
-
"url": "https://github.com/MATCHUP-LABS/
|
|
15
|
-
"directory": "mcp-server"
|
|
14
|
+
"url": "https://github.com/MATCHUP-LABS/api-ventures.git",
|
|
15
|
+
"directory": "products/nyc-fhv-intelligence-api/mcp-server"
|
|
16
16
|
},
|
|
17
17
|
"homepage": "https://fhv.matchup.dev",
|
|
18
|
+
"bugs": {
|
|
19
|
+
"url": "https://github.com/MATCHUP-LABS/api-ventures/issues"
|
|
20
|
+
},
|
|
21
|
+
"engines": {
|
|
22
|
+
"node": ">=18.17"
|
|
23
|
+
},
|
|
18
24
|
"keywords": [
|
|
19
25
|
"mcp",
|
|
20
26
|
"model-context-protocol",
|
|
@@ -24,12 +30,21 @@
|
|
|
24
30
|
"fhv",
|
|
25
31
|
"license-verification",
|
|
26
32
|
"rideshare",
|
|
27
|
-
"ai-agent"
|
|
33
|
+
"ai-agent",
|
|
34
|
+
"nemt",
|
|
35
|
+
"fleet-management",
|
|
36
|
+
"compliance",
|
|
37
|
+
"wheelchair-accessible",
|
|
38
|
+
"wav",
|
|
39
|
+
"government-data",
|
|
40
|
+
"transportation"
|
|
28
41
|
],
|
|
29
42
|
"files": [
|
|
30
43
|
"dist",
|
|
31
44
|
"server.json",
|
|
32
|
-
"README.md"
|
|
45
|
+
"README.md",
|
|
46
|
+
"llms.txt",
|
|
47
|
+
"llms-full.txt"
|
|
33
48
|
],
|
|
34
49
|
"scripts": {
|
|
35
50
|
"build": "tsc",
|
package/server.json
CHANGED
|
@@ -3,17 +3,18 @@
|
|
|
3
3
|
"name": "io.github.MatchupLabs/nycfhv",
|
|
4
4
|
"title": "NYC FHV Intelligence API",
|
|
5
5
|
"description": "Real-time NYC TLC for-hire vehicle license verification and renewal-window lead lookups via MCP.",
|
|
6
|
-
"version": "0.1.
|
|
6
|
+
"version": "0.1.1",
|
|
7
7
|
"repository": {
|
|
8
|
-
"url": "https://github.com/MATCHUP-LABS/
|
|
9
|
-
"source": "github"
|
|
8
|
+
"url": "https://github.com/MATCHUP-LABS/api-ventures",
|
|
9
|
+
"source": "github",
|
|
10
|
+
"subfolder": "products/nyc-fhv-intelligence-api/mcp-server"
|
|
10
11
|
},
|
|
11
12
|
"packages": [
|
|
12
13
|
{
|
|
13
14
|
"registryType": "npm",
|
|
14
15
|
"registryBaseUrl": "https://registry.npmjs.org",
|
|
15
16
|
"identifier": "@matchuplabs/nycfhv-mcp",
|
|
16
|
-
"version": "0.1.
|
|
17
|
+
"version": "0.1.1",
|
|
17
18
|
"transport": {
|
|
18
19
|
"type": "stdio"
|
|
19
20
|
},
|