@tcliplab/transit-mcp 0.1.0 → 0.1.2
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 +60 -4
- package/build/index.js +44 -15
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,11 +1,67 @@
|
|
|
1
1
|
# Transit API Server
|
|
2
2
|
|
|
3
|
-
An MCP server for Transit API, a Japanese public transit API built on `https://api.transit.ls8h.com/`.
|
|
3
|
+
An unofficial local MCP server for Transit API, a Japanese public transit API built on `https://api.transit.ls8h.com/`.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
In most cases, you should use the official MCP connector at `https://api.transit.ls8h.com/mcp`.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
This package exists as a local `npm` / `npx`-based wrapper and as a base for future wrapper tools and experiments.
|
|
8
|
+
It also includes lightweight result previews, which may make the first-step UX a little smoother.
|
|
8
9
|
|
|
9
|
-
|
|
10
|
+
Why `npx`: this package is packaged so it can be tried without a local install or a separate service setup.
|
|
11
|
+
That may make it a useful example of how the same API can be wrapped as a local `npm` / `npx`-driven MCP server, with the distribution model and adapter layer being part of the value.
|
|
12
|
+
|
|
13
|
+
## Available Tools
|
|
14
|
+
|
|
15
|
+
These tools follow the shape and coverage of the original Transit API.
|
|
16
|
+
|
|
17
|
+
- `plan_journey` - search a route between two places
|
|
18
|
+
- `guidance_plan` - generate route guidance text
|
|
19
|
+
- `suggest_locations` - search location candidates
|
|
20
|
+
- `suggest_places` - search stations and place candidates
|
|
21
|
+
- `get_station` - fetch station details
|
|
22
|
+
- `get_station_departures` - fetch departures from a station
|
|
23
|
+
- `list_feeds` - list available feeds
|
|
24
|
+
- `list_operators` - list available operators
|
|
25
|
+
|
|
26
|
+
## Install
|
|
27
|
+
|
|
28
|
+
Use `npx` for quick access.
|
|
29
|
+
|
|
30
|
+
If you prefer, you can build and run it yourself.
|
|
31
|
+
|
|
32
|
+
## Connect Claude Desktop
|
|
33
|
+
|
|
34
|
+
Add the server to your Claude Desktop config:
|
|
35
|
+
|
|
36
|
+
```json
|
|
37
|
+
{
|
|
38
|
+
"mcpServers": {
|
|
39
|
+
"transit-mcp": {
|
|
40
|
+
"command": "npx",
|
|
41
|
+
"args": ["-y", "@tcliplab/transit-mcp@beta"]
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Connect Codex
|
|
48
|
+
|
|
49
|
+
Add the server to your Codex config:
|
|
50
|
+
|
|
51
|
+
```toml
|
|
52
|
+
[mcp_servers.transit_mcp]
|
|
53
|
+
command = "npx"
|
|
54
|
+
args = ["-y", "@tcliplab/transit-mcp@beta"]
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## API Documentation
|
|
58
|
+
|
|
59
|
+
Transit API is available at `https://api.transit.ls8h.com/`.
|
|
60
|
+
|
|
61
|
+
The server uses the public REST API directly and does not require extra credentials.
|
|
62
|
+
|
|
63
|
+
## About
|
|
64
|
+
|
|
65
|
+
This package is currently unofficial.
|
|
10
66
|
|
|
11
67
|
No license is granted at this time. OSS release is planned after permission and scope are clarified.
|
package/build/index.js
CHANGED
|
@@ -1,7 +1,20 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { readFileSync } from "node:fs";
|
|
1
3
|
import { McpServer } from "@modelcontextprotocol/server";
|
|
2
4
|
import { StdioServerTransport } from "@modelcontextprotocol/server/stdio";
|
|
3
5
|
import * as z from "zod/v4";
|
|
4
6
|
const API_BASE = "https://api.transit.ls8h.com";
|
|
7
|
+
const REQUEST_TIMEOUT_MS = 20_000;
|
|
8
|
+
function readPackageVersion() {
|
|
9
|
+
try {
|
|
10
|
+
const packageJson = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8"));
|
|
11
|
+
return typeof packageJson.version === "string" ? packageJson.version : "0.0.0";
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
return "0.0.0";
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
const SERVER_VERSION = readPackageVersion();
|
|
5
18
|
function toSearchParams(params) {
|
|
6
19
|
const searchParams = new URLSearchParams();
|
|
7
20
|
for (const [key, value] of Object.entries(params)) {
|
|
@@ -18,24 +31,40 @@ async function fetchTransit(path, params = {}) {
|
|
|
18
31
|
searchParams.forEach((value, key) => {
|
|
19
32
|
url.searchParams.set(key, value);
|
|
20
33
|
});
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
});
|
|
26
|
-
const rawText = await response.text();
|
|
27
|
-
let data = rawText;
|
|
34
|
+
const controller = new AbortController();
|
|
35
|
+
const timeoutId = setTimeout(() => {
|
|
36
|
+
controller.abort();
|
|
37
|
+
}, REQUEST_TIMEOUT_MS);
|
|
28
38
|
try {
|
|
29
|
-
|
|
39
|
+
const response = await fetch(url, {
|
|
40
|
+
headers: {
|
|
41
|
+
accept: "application/json",
|
|
42
|
+
},
|
|
43
|
+
signal: controller.signal,
|
|
44
|
+
});
|
|
45
|
+
const rawText = await response.text();
|
|
46
|
+
let data = rawText;
|
|
47
|
+
try {
|
|
48
|
+
data = JSON.parse(rawText);
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
// Keep raw text when the endpoint does not return JSON.
|
|
52
|
+
}
|
|
53
|
+
if (!response.ok) {
|
|
54
|
+
const detail = typeof data === "string" ? data : JSON.stringify(data, null, 2);
|
|
55
|
+
throw new Error(`Transit API ${response.status} ${response.statusText}: ${detail}`);
|
|
56
|
+
}
|
|
57
|
+
return data;
|
|
30
58
|
}
|
|
31
|
-
catch {
|
|
32
|
-
|
|
59
|
+
catch (error) {
|
|
60
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
61
|
+
throw new Error(`Transit API request timed out after ${REQUEST_TIMEOUT_MS}ms`);
|
|
62
|
+
}
|
|
63
|
+
throw error;
|
|
33
64
|
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
throw new Error(`Transit API ${response.status} ${response.statusText}: ${detail}`);
|
|
65
|
+
finally {
|
|
66
|
+
clearTimeout(timeoutId);
|
|
37
67
|
}
|
|
38
|
-
return data;
|
|
39
68
|
}
|
|
40
69
|
function formatServiceSeconds(seconds) {
|
|
41
70
|
const day = 86_400;
|
|
@@ -195,7 +224,7 @@ const stationInput = z.object({
|
|
|
195
224
|
});
|
|
196
225
|
const server = new McpServer({
|
|
197
226
|
name: "transit-mcp",
|
|
198
|
-
version:
|
|
227
|
+
version: SERVER_VERSION,
|
|
199
228
|
});
|
|
200
229
|
server.registerTool("plan_journey", {
|
|
201
230
|
title: "Plan journey",
|