fortrip 0.3.0 → 1.0.0
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/LICENSE +21 -0
- package/README.md +185 -74
- package/dist/chunk-OBK2KTLC.js +16333 -0
- package/dist/cli.js +253 -570
- package/dist/mcp-bridge-VEJ33LYD.js +191 -0
- package/package.json +18 -14
- package/AGENT_GUIDE.md +0 -133
- package/guides/planning.md +0 -54
- package/skills/fortrip-hotels/SKILL.md +0 -20
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 FortripEngineering
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,105 +1,216 @@
|
|
|
1
|
-
# fortrip
|
|
1
|
+
# fortrip
|
|
2
2
|
|
|
3
|
-
Search,
|
|
4
|
-
The npm package and the command
|
|
3
|
+
Search hotels, check live room rates and book with a payment link, from the
|
|
4
|
+
terminal or an AI agent. Hotels only for now. The npm package and the command
|
|
5
|
+
are both `fortrip`.
|
|
5
6
|
|
|
6
7
|
```bash
|
|
7
|
-
npx fortrip login
|
|
8
|
-
npx fortrip search --query Bangkok --check-in 2026-11-10 --check-out 2026-11-12
|
|
8
|
+
npx -y fortrip login
|
|
9
|
+
npx -y fortrip search --query Bangkok --check-in 2026-11-10 --check-out 2026-11-12
|
|
9
10
|
```
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
## Install and run
|
|
13
|
+
|
|
14
|
+
Node.js 22 or newer. Run it with `npx`, which needs no install:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npx -y fortrip <command>
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
or install it once and run `fortrip <command>`:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npm install --global fortrip
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
`fortrip --help` lists the commands, `fortrip <command> --help` one command's
|
|
27
|
+
flags, and `fortrip --version` prints the version.
|
|
28
|
+
|
|
29
|
+
Upgrading from 0.3: 1.0 signs in with OAuth, so a 0.3 sign-in is not reused;
|
|
30
|
+
run `fortrip login` once. A `FORTRIP_TOKEN` from 0.3 is no longer accepted.
|
|
31
|
+
`fortrip mcp` replaces the separate `fortrip-mcp` package.
|
|
32
|
+
|
|
33
|
+
## Sign in
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
fortrip login
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
`login` prints a code and a link on stderr, opens the link in your browser
|
|
40
|
+
(not with `--no-browser`), and waits until you sign in to Fortrip and approve.
|
|
41
|
+
It then prints your account.
|
|
42
|
+
|
|
43
|
+
An AI agent can't sit in `login`, so any other command that needs a sign-in
|
|
44
|
+
doesn't wait: it exits with code 3 and prints `loginUrl`, `userCode` and
|
|
45
|
+
`expiresInSeconds` as JSON on stderr. The agent shows the link to the user;
|
|
46
|
+
once the user has approved it in the browser, the agent reruns the same
|
|
47
|
+
command, which finishes signing in and carries on. Commands that run in
|
|
48
|
+
parallel share one link. When Fortrip stops accepting the saved sign-in (it
|
|
49
|
+
was revoked, or it expired and couldn't be renewed), the command does the same
|
|
50
|
+
and keeps the old sign-in until the new link is approved.
|
|
51
|
+
|
|
52
|
+
You stay signed in. Access tokens last 24 hours and the CLI renews them
|
|
53
|
+
itself, before they run out; refresh tokens don't expire, so the sign-in lasts
|
|
54
|
+
until you run `fortrip logout`, which revokes this machine's sign-in and
|
|
55
|
+
deletes it (other machines stay signed in). `fortrip whoami` prints the
|
|
56
|
+
signed-in account.
|
|
57
|
+
|
|
58
|
+
The sign-in is saved in `~/.config/fortrip/credentials.json` (`$XDG_CONFIG_HOME`
|
|
59
|
+
is honoured), mode `0600`, per API URL, so a token is only sent to the server
|
|
60
|
+
that issued it.
|
|
61
|
+
|
|
62
|
+
If a new or renewed sign-in can't be saved (the file stays busy or turns out to
|
|
63
|
+
be damaged), `search`, `hotel`, `rates`, `book` and `whoami` still work for that
|
|
64
|
+
run, with the new token. The sign-in is kept in a `credentials.recovered-*.json`
|
|
65
|
+
file next to the credentials file, and the command's JSON output carries a
|
|
66
|
+
`warning` and, when the sign-in could be kept, that file in `recoveryFile`.
|
|
67
|
+
Later commands use it, and the next successful save merges it back. `login`
|
|
68
|
+
doesn't carry on in that case: it exits 1, with `recoveryFile` in the error, and
|
|
69
|
+
the sign-in is kept in that file all the same.
|
|
70
|
+
|
|
71
|
+
If the directory itself can't be written (a read-only home, as in some agent
|
|
72
|
+
sandboxes), `login` exits 1 before it asks you to approve anything, and any
|
|
73
|
+
other command that needs to save a sign-in exits 1 too. The error says to set
|
|
74
|
+
`XDG_CONFIG_HOME` to a directory that can be written, or to set `FORTRIP_TOKEN`.
|
|
12
75
|
|
|
13
76
|
## Commands
|
|
14
77
|
|
|
15
78
|
| Command | What it does |
|
|
16
79
|
|---|---|
|
|
17
|
-
| `
|
|
18
|
-
| `
|
|
19
|
-
| `
|
|
20
|
-
| `
|
|
21
|
-
| `
|
|
22
|
-
| `
|
|
23
|
-
| `
|
|
80
|
+
| `search` | Find hotels with indicative prices |
|
|
81
|
+
| `hotel <hotelId>` | Static hotel detail: description, policies, facilities and photos |
|
|
82
|
+
| `rates` | Live rooms and rates for up to 15 hotels |
|
|
83
|
+
| `book` | Create an order and get a payment link |
|
|
84
|
+
| `login` | Sign in through the browser (device code) |
|
|
85
|
+
| `logout` | Revoke and forget the saved token |
|
|
86
|
+
| `whoami` | Show the signed-in account |
|
|
87
|
+
| `guide [topic]` | Print the guide for AI agents (Markdown) |
|
|
88
|
+
| `mcp` | Run an MCP server over stdio for local clients, bridged to Fortrip's hosted server |
|
|
24
89
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
90
|
+
```bash
|
|
91
|
+
fortrip rates --hotel <hotelId> --check-in 2026-11-10 --check-out 2026-11-12 --rooms 1 --adults 2
|
|
92
|
+
```
|
|
28
93
|
|
|
29
|
-
|
|
94
|
+
`search`, `rates` and `book` also accept `--body '<json>'` or
|
|
95
|
+
`--body @file.json` with the raw request body; flags override its fields.
|
|
30
96
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
| 1 | Other error |
|
|
35
|
-
| 2 | Invalid arguments (local or HTTP 400) |
|
|
36
|
-
| 3 | Not logged in / token revoked (HTTP 401) |
|
|
37
|
-
| 4 | Rate limited (HTTP 429; `retryAfterSeconds` on stderr) |
|
|
97
|
+
`--adults` and `--child-age` are per room, and every room has the same
|
|
98
|
+
occupancy: 2 rooms for 4 adults is `--rooms 2 --adults 2`. `rates` and `book`
|
|
99
|
+
both require `--rooms` and `--adults`.
|
|
38
100
|
|
|
39
|
-
|
|
101
|
+
`book` creates an unpaid order and prints a payment link for it. Nothing is
|
|
102
|
+
charged until the person pays on the page the link opens.
|
|
40
103
|
|
|
41
|
-
|
|
42
|
-
(`$XDG_CONFIG_HOME` is honoured), mode `0600`. Tokens are stored per API URL,
|
|
43
|
-
so a token is only ever sent to the server that issued it.
|
|
44
|
-
- Without a token, any other command starts a device login and exits 3 with
|
|
45
|
-
`loginUrl` on stderr instead of waiting. Once that link is approved in the
|
|
46
|
-
browser, rerunning the command saves the token and carries on. This is how
|
|
47
|
-
AI agents sign in, since they can't sit in `login`.
|
|
48
|
-
- `FORTRIP_TOKEN` overrides the saved login (CI, remote sandboxes).
|
|
49
|
-
- `FORTRIP_API_URL` overrides the base URL (default `https://fortrip.ai`).
|
|
50
|
-
Plain `http` is only accepted for `localhost`.
|
|
51
|
-
- `FORTRIP_CURRENCY` sets the default `--currency` for `search` and `rates`
|
|
52
|
-
(`CNY` or `USD`; the API defaults to `CNY`). Display only: `book`
|
|
53
|
-
charges the currency it returns.
|
|
104
|
+
## For AI agents
|
|
54
105
|
|
|
55
|
-
|
|
106
|
+
```bash
|
|
107
|
+
npx -y fortrip guide # when to use the CLI, call order, sign-in, what to show before a payment link
|
|
108
|
+
npx -y fortrip guide planning # flexible dates, budgets, split stays, several destinations
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Both print Markdown, with `fortrip@latest` replaced by the running version, so
|
|
112
|
+
an agent keeps using the same CLI for the whole conversation. The guide is
|
|
113
|
+
written once in
|
|
114
|
+
[`@fortrip/agent-contract`](https://github.com/FortripEngineering/fortrip/tree/main/packages/contract/guide)
|
|
115
|
+
and compiled into the CLI.
|
|
56
116
|
|
|
57
|
-
|
|
117
|
+
For agents that can run shell commands, the same guide is also a skill:
|
|
58
118
|
|
|
59
119
|
```bash
|
|
60
|
-
npx skills add FortripEngineering/fortrip-cli
|
|
120
|
+
npx skills add FortripEngineering/fortrip --skill fortrip-cli
|
|
61
121
|
```
|
|
62
122
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
with
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
123
|
+
## MCP server
|
|
124
|
+
|
|
125
|
+
`fortrip mcp` runs an MCP server on stdio for clients that start local
|
|
126
|
+
servers. It forwards to Fortrip's hosted MCP server, `https://fortrip.ai/api/mcp`,
|
|
127
|
+
with your saved sign-in. Sign in once with `npx -y fortrip login` before you
|
|
128
|
+
add the server to a client.
|
|
129
|
+
|
|
130
|
+
If the client starts the server before you have, the server fails to connect:
|
|
131
|
+
its first request, `initialize`, is answered with a JSON-RPC error (`-32001`)
|
|
132
|
+
whose message says to run `npx -y fortrip login` in a terminal, or to open the
|
|
133
|
+
sign-in link it names and approve it. Clients typically close the connection
|
|
134
|
+
after a failed `initialize`, so sign in (or approve that link), then restart the
|
|
135
|
+
server or reconnect it (`/mcp` in Claude Code). If a sign-in stops working
|
|
136
|
+
later, only the request that hit it fails with the same kind of error, and the
|
|
137
|
+
server keeps running.
|
|
138
|
+
|
|
139
|
+
Claude Desktop (Settings, Developer, Edit Config; on macOS
|
|
140
|
+
`~/Library/Application Support/Claude/claude_desktop_config.json`, on Windows
|
|
141
|
+
`%APPDATA%\Claude\claude_desktop_config.json`) and Cursor (`~/.cursor/mcp.json`,
|
|
142
|
+
or `.cursor/mcp.json` in a project):
|
|
143
|
+
|
|
144
|
+
```json
|
|
145
|
+
{
|
|
146
|
+
"mcpServers": {
|
|
147
|
+
"fortrip": {
|
|
148
|
+
"command": "npx",
|
|
149
|
+
"args": ["-y", "fortrip", "mcp"]
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
```
|
|
75
154
|
|
|
76
|
-
|
|
155
|
+
Claude Code:
|
|
77
156
|
|
|
78
157
|
```bash
|
|
79
|
-
|
|
80
|
-
pnpm dev search --query Bangkok ... # run from source
|
|
81
|
-
pnpm test
|
|
82
|
-
pnpm typecheck
|
|
83
|
-
pnpm build # dist/cli.js
|
|
158
|
+
claude mcp add fortrip -- npx -y fortrip mcp
|
|
84
159
|
```
|
|
85
160
|
|
|
86
|
-
|
|
161
|
+
Codex, with `codex mcp add fortrip -- npx -y fortrip mcp` or in
|
|
162
|
+
`~/.codex/config.toml`:
|
|
87
163
|
|
|
88
|
-
|
|
164
|
+
```toml
|
|
165
|
+
[mcp_servers.fortrip]
|
|
166
|
+
command = "npx"
|
|
167
|
+
args = ["-y", "fortrip", "mcp"]
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
Clients that support remote MCP servers with OAuth don't need the CLI: add
|
|
171
|
+
`https://fortrip.ai/api/mcp` as a remote server and sign in to Fortrip in the
|
|
172
|
+
browser when the client asks. In Claude Code, that is
|
|
173
|
+
`claude mcp add --transport http fortrip https://fortrip.ai/api/mcp`.
|
|
174
|
+
|
|
175
|
+
## Environment variables
|
|
176
|
+
|
|
177
|
+
| Variable | Meaning |
|
|
178
|
+
|---|---|
|
|
179
|
+
| `FORTRIP_TOKEN` | An access token, used instead of the saved sign-in. It lasts at most 24 hours, so it suits one sandbox session or one CI run, not standing CI. It isn't tied to a server: it is sent to whatever `FORTRIP_API_URL` points at. If Fortrip doesn't accept it, or it contains a line break or another character that can't be sent in a header, commands exit 3 with `tokenSource: "FORTRIP_TOKEN"` and no `loginUrl`; the error never repeats the token. |
|
|
180
|
+
| `FORTRIP_API_URL` | The base URL (default `https://fortrip.ai`). Plain `http` is only accepted for `localhost`. |
|
|
181
|
+
| `FORTRIP_CURRENCY` | The default `--currency` for `search` and `rates` (`CNY` or `USD`; the API uses `CNY` when nothing sets one). It only changes how prices are shown: `book` charges the currency it returns. |
|
|
89
182
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
183
|
+
## Output and exit codes
|
|
184
|
+
|
|
185
|
+
Data commands (`search`, `hotel`, `rates`, `book`, `login`, `logout`,
|
|
186
|
+
`whoami`) print JSON on stdout. `guide` prints Markdown, and `fortrip mcp`
|
|
187
|
+
speaks MCP over stdio. Errors are JSON on stderr, with an `error` message, the
|
|
188
|
+
`exitCode` and any details.
|
|
189
|
+
|
|
190
|
+
| Code | Meaning |
|
|
191
|
+
|---|---|
|
|
192
|
+
| 0 | Success |
|
|
193
|
+
| 1 | Other error (`retryable: true` on stderr: worth one retry) |
|
|
194
|
+
| 2 | Invalid arguments (local or HTTP 400) |
|
|
195
|
+
| 3 | Not signed in, or the sign-in wasn't accepted (HTTP 401); `loginUrl` on stderr |
|
|
196
|
+
| 4 | Rate limited (HTTP 429; `retryAfterSeconds` on stderr) |
|
|
197
|
+
|
|
198
|
+
## Support
|
|
199
|
+
|
|
200
|
+
For changes, cancellations, refunds or other help with a booking, email
|
|
201
|
+
[info@fortrip.ai](mailto:info@fortrip.ai) with the booking's order link
|
|
202
|
+
(`orderUrl`).
|
|
203
|
+
|
|
204
|
+
## Releasing
|
|
93
205
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
206
|
+
Both packages in this repository, `fortrip` and `@fortrip/agent-contract`,
|
|
207
|
+
are released together from a `vX.Y.Z` tag. See
|
|
208
|
+
[Releasing](https://github.com/FortripEngineering/fortrip#releasing) in the
|
|
209
|
+
repository's README.
|
|
97
210
|
|
|
98
|
-
|
|
99
|
-
git checkout main && git pull
|
|
100
|
-
git tag v0.2.0 && git push origin v0.2.0
|
|
101
|
-
```
|
|
211
|
+
## License
|
|
102
212
|
|
|
103
|
-
The
|
|
104
|
-
|
|
105
|
-
|
|
213
|
+
The code and documentation in this repository are licensed under the
|
|
214
|
+
[MIT License](https://github.com/FortripEngineering/fortrip/blob/main/LICENSE).
|
|
215
|
+
This license does not grant access to the hosted Fortrip service, hotel
|
|
216
|
+
inventory, or third-party data.
|