diff --git a/MCP_README.md b/MCP_README.md
index 09b8d78a..7d610379 100644
--- a/MCP_README.md
+++ b/MCP_README.md
@@ -8,30 +8,81 @@
## 🚀 Quick Start
-### Use with Claude Desktop
+`@terminal49/mcp` is a private workspace in this repository. Connect to the hosted server, or build the stdio server from a clone.
-Add to your Claude Desktop config (`~/Library/Application Support/Claude/claude_desktop_config.json`):
+### Use the hosted server
+
+The connector URL is `https://mcp.terminal49.com` (Streamable HTTP). Use that root origin, with no extra path. It is the canonical OAuth resource identifier.
+
+**OAuth 2.1 (recommended).** No API key. Add `https://mcp.terminal49.com` to your client. It discovers the authorization server (`https://auth.terminal49.com`) via protected resource metadata, registers itself with Dynamic Client Registration, and opens your browser so you can sign in with your Terminal49 credentials.
+
+In Claude, add Terminal49 from the [Claude Directory](https://claude.ai/directory/connectors/terminal49). For a custom connector, go to **Settings → Connectors → Add custom connector**, enter `Terminal49` as the name, use `https://mcp.terminal49.com`, and leave the advanced OAuth fields empty.
```json
{
"mcpServers": {
"terminal49": {
- "command": "npx",
- "args": ["-y", "@terminal49/mcp"],
- "env": {
- "T49_API_TOKEN": "your_token_here"
+ "url": "https://mcp.terminal49.com"
+ }
+ }
+}
+```
+
+**API key.** For clients that can't run a browser OAuth flow, create a key in the [developer portal](https://app.terminal49.com/developers/api-keys) and pass `Authorization: Token YOUR_API_KEY`. Use the `Token` scheme for API keys. The `Bearer` scheme is used for OAuth access tokens, which OAuth clients obtain automatically.
+
+```json
+{
+ "mcpServers": {
+ "terminal49": {
+ "url": "https://mcp.terminal49.com",
+ "headers": {
+ "Authorization": "Token YOUR_API_KEY"
}
}
}
}
```
-**Get your API token:** https://app.terminal49.com/developers/api-keys
+claude.ai and Claude Desktop cannot send a static API-key header. They authenticate through the OAuth connector flow. For an API key on your own machine, run the stdio server in the next section. The local process reads `T49_API_TOKEN` instead of an `Authorization` header.
+
+### Run it from this repository
+
+Use Node.js 24.22.1 or a newer Node 24 release (`.tool-versions` pins `24.22.1`). From a clone:
+
+```bash
+git clone https://github.com/Terminal49/API.git
+cd API
+npm ci
+npm run build --workspace @terminal49/sdk
+npm run build --workspace @terminal49/mcp
+```
+
+The stdio entrypoint is `packages/mcp/dist/index.js`. Set `T49_API_TOKEN` to an API key from the [developer portal](https://app.terminal49.com/developers/api-keys). The process exits if that variable is unset.
-### Deploy to Vercel
+```bash
+T49_API_TOKEN=YOUR_API_KEY node packages/mcp/dist/index.js
+```
+
+Point a local MCP client at that file. Claude Desktop's config is `~/Library/Application Support/Claude/claude_desktop_config.json` on macOS, `%APPDATA%\Claude\claude_desktop_config.json` on Windows, and `~/.config/Claude/claude_desktop_config.json` on Linux:
+
+```json
+{
+ "mcpServers": {
+ "terminal49": {
+ "command": "node",
+ "args": ["/absolute/path/to/API/packages/mcp/dist/index.js"],
+ "env": {
+ "T49_API_TOKEN": "YOUR_API_KEY"
+ }
+ }
+ }
+}
+```
+
+### Deploy your own copy to Vercel
-1. Click "Deploy" button above
-2. Add environment variable: `T49_API_TOKEN=your_token_here`
+1. Click the Deploy button above
+2. Add environment variable: `T49_API_TOKEN=YOUR_API_KEY`
3. Your MCP server will be at: `https://your-deployment.vercel.app/api/mcp`
---
@@ -128,11 +179,11 @@ Pre-built workflows for common tasks:
│ └── README.md # Full documentation
```
-The MCP package consumes published `@terminal49/sdk` by default.
+The MCP server depends on the workspace package `@terminal49/sdk`. Build that package before you build `packages/mcp`.
**Stack:**
- [Model Context Protocol SDK](https://modelcontextprotocol.io) v1.29.0
-- Terminal49 TypeScript SDK v0.2.0
+- Terminal49 TypeScript SDK v0.6.0
- [Sentry MCP Monitoring](https://docs.sentry.io/ai/monitoring/mcp/) via `@sentry/node` v10.55.0 when `SENTRY_DSN` is configured
- TypeScript
- Vercel Serverless Functions
@@ -143,29 +194,28 @@ The MCP package consumes published `@terminal49/sdk` by default.
## 🔧 Development
### Prerequisites
-- Node.js 24.x
-- Terminal49 API token
-### Local Setup
+- Node.js 24.22.1 or a newer Node 24 release
+- A Terminal49 API key from the [developer portal](https://app.terminal49.com/developers/api-keys), for tool calls that reach the API
-```bash
-# Install dependencies
-npm install
-
-cd packages/mcp
-T49_SDK_SOURCE=published npm run sdk:setup
+### Local setup
-# Optional: switch to local SDK build for development
-# T49_SDK_SOURCE=local npm run sdk:setup
+From the repository root, on Node.js 24.22.1 or a newer Node 24 release:
-# Run MCP server locally (stdio)
-npm run dev
+```bash
+npm ci
+npm run build --workspace @terminal49/sdk
+npm run build --workspace @terminal49/mcp
+```
-# Run tests
-npm test
+Smoke-test the built stdio entrypoint. This sends `initialize`, then `tools/list`:
-# Build
-npm run build
+```bash
+printf '%s\n' \
+ '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"smoke","version":"1.0"}}}' \
+ '{"jsonrpc":"2.0","method":"notifications/initialized"}' \
+ '{"jsonrpc":"2.0","id":2,"method":"tools/list"}' \
+ | T49_API_TOKEN=YOUR_API_KEY node packages/mcp/dist/index.js
```
### Testing with MCP Inspector
@@ -209,7 +259,7 @@ vercel deploy --prod
```
**Environment Variables:**
-- `T49_API_TOKEN` - Your Terminal49 API token (required)
+- `T49_API_TOKEN` - Your Terminal49 API key (required for this self-hosted deploy)
- `T49_API_BASE_URL` - Optional (defaults to https://api.terminal49.com)
- `SENTRY_DSN` - Optional; enables Sentry MCP Monitoring
- `SENTRY_TRACES_SAMPLE_RATE` - Optional trace sample rate (`1.0` by default)
@@ -231,7 +281,7 @@ MIT
- [Terminal49 API Docs](https://docs.terminal49.com)
- [Model Context Protocol](https://modelcontextprotocol.io)
-- [Get API Token](https://app.terminal49.com/developers/api-keys)
+- [Create an API key](https://app.terminal49.com/developers/api-keys)
- [Full MCP Documentation](packages/mcp/README.md)
---
diff --git a/README.md b/README.md
index 2b48cfa3..8d597fb8 100644
--- a/README.md
+++ b/README.md
@@ -12,7 +12,7 @@ This repository holds the public developer docs, the OpenAPI spec, and the clien
| OpenAPI spec (source of truth for the API reference) | [`docs/openapi.json`](docs/openapi.json) | [API reference](https://terminal49.com/docs/api-docs/api-reference/shipments/list-shipments) |
| TypeScript SDK | [`sdks/typescript-sdk/`](sdks/typescript-sdk/) | [`@terminal49/sdk`](https://www.npmjs.com/package/@terminal49/sdk) on npm |
| CLI (`t49`) | [`sdks/typescript-sdk-cli/`](sdks/typescript-sdk-cli/) | [`@terminal49/cli`](https://www.npmjs.com/package/@terminal49/cli) on npm |
-| MCP server | [`packages/mcp/`](packages/mcp/) | `@terminal49/mcp`, hosted at `https://mcp.terminal49.com` |
+| MCP server | [`packages/mcp/`](packages/mcp/) | Hosted at `https://mcp.terminal49.com`. `@terminal49/mcp` is a private workspace; build it from this repo |
| MCP OAuth gateway | [`api/`](api/) | Vercel functions behind `https://mcp.terminal49.com` |
| Postman collection (generated from the OpenAPI spec) | [`Terminal49-API.postman_collection.json`](Terminal49-API.postman_collection.json) | Import into Postman |
@@ -58,9 +58,9 @@ t49 track MSCU1234567
### Connect the MCP server
-Point your MCP client at `https://mcp.terminal49.com`. Use the root URL, not `/mcp`. The client signs you in with OAuth, so you do not need an API key. In Claude, add Terminal49 from the [Claude Directory](https://claude.ai/directory/connectors/terminal49).
+Point your MCP client at `https://mcp.terminal49.com` (Streamable HTTP). Use that root origin, with no extra path. It is the canonical OAuth resource identifier. The client signs you in with OAuth, so you do not need an API key. In Claude, add Terminal49 from the [Claude Directory](https://claude.ai/directory/connectors/terminal49).
-For ChatGPT, Claude Code, Cursor, VS Code, and other clients, see the [MCP server docs](https://terminal49.com/docs/mcp/home).
+Clients that can't run a browser OAuth flow send `Authorization: Token YOUR_API_KEY`. For ChatGPT, Claude Code, Cursor, VS Code, and other clients, see the [MCP server docs](https://terminal49.com/docs/mcp/home). To run the stdio server on your machine, follow [Run it from this repository](MCP_README.md#run-it-from-this-repository).
## Develop in this repository
diff --git a/docs/api-docs/in-depth-guides/mcp.mdx b/docs/api-docs/in-depth-guides/mcp.mdx
index 9358aec3..c7ed897e 100644
--- a/docs/api-docs/in-depth-guides/mcp.mdx
+++ b/docs/api-docs/in-depth-guides/mcp.mdx
@@ -122,14 +122,24 @@ Add to `.cursor/mcp.json` in your project (or `~/.cursor/mcp.json` for all proje
### Local stdio (development)
-For local development without a hosted server:
+`@terminal49/mcp` is a private workspace in this repository. Build it from a clone when you want a local stdio process instead of the hosted server. Use Node.js 24.22.1 or a newer Node 24 release (`.tool-versions` pins `24.22.1`).
+
+```bash
+git clone https://github.com/Terminal49/API.git
+cd API
+npm ci
+npm run build --workspace @terminal49/sdk
+npm run build --workspace @terminal49/mcp
+```
+
+The stdio entrypoint is `packages/mcp/dist/index.js`. It reads `T49_API_TOKEN` and exits if that variable is unset. Create the key in the [developer portal](https://app.terminal49.com/developers/api-keys).
```json
{
"mcpServers": {
"terminal49": {
"command": "node",
- "args": ["/path/to/API/packages/mcp/dist/index.js"],
+ "args": ["/absolute/path/to/API/packages/mcp/dist/index.js"],
"env": {
"T49_API_TOKEN": "YOUR_API_KEY"
}
@@ -138,24 +148,7 @@ For local development without a hosted server:
}
```
-
-Build the MCP server first:
-`cd packages/mcp && npm install && T49_SDK_SOURCE=published npm run sdk:setup && npm run build`
-
-
-
-Use published SDK by default:
-```bash
-cd packages/mcp
-T49_SDK_SOURCE=published npm run sdk:setup
-```
-
-Use local SDK build during development:
-```bash
-cd packages/mcp
-T49_SDK_SOURCE=local npm run sdk:setup
-```
-
+The MCP server depends on the workspace package `@terminal49/sdk`. The build above compiles that package first.
---
@@ -204,10 +197,13 @@ Need test container numbers? See [Test Numbers](/api-docs/useful-info/test-numbe
If using the hosted server, check your Terminal49 dashboard for API logs.
-If running locally:
+If running locally, from the repository root after the build above:
```bash
-cd packages/mcp
-T49_API_TOKEN=YOUR_API_KEY npm run mcp:stdio 2>&1 | head -20
+printf '%s\n' \
+ '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"smoke","version":"1.0"}}}' \
+ '{"jsonrpc":"2.0","method":"notifications/initialized"}' \
+ '{"jsonrpc":"2.0","id":2,"method":"tools/list"}' \
+ | T49_API_TOKEN=YOUR_API_KEY node packages/mcp/dist/index.js
```
@@ -377,16 +373,19 @@ Clients can remove tools per request with the `X-T49-MCP-Toolsets` and `X-T49-MC
## Testing locally
```bash
-# Build the MCP server
-cd packages/mcp
-npm install
-npm run build
-
-# Test tools/list
-echo '{"jsonrpc":"2.0","method":"tools/list","id":1}' | T49_API_TOKEN=YOUR_API_KEY npm run mcp:stdio
-
-# Test search_container
-echo '{"jsonrpc":"2.0","method":"tools/call","params":{"name":"search_container","arguments":{"query":"CAIU1234567"}},"id":2}' | T49_API_TOKEN=YOUR_API_KEY npm run mcp:stdio
+# Build the MCP server from a clone (Node.js 24.22.1 or a newer Node 24 release)
+git clone https://github.com/Terminal49/API.git
+cd API
+npm ci
+npm run build --workspace @terminal49/sdk
+npm run build --workspace @terminal49/mcp
+
+# initialize, then tools/list, on the built stdio entrypoint
+printf '%s\n' \
+ '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"smoke","version":"1.0"}}}' \
+ '{"jsonrpc":"2.0","method":"notifications/initialized"}' \
+ '{"jsonrpc":"2.0","id":2,"method":"tools/list"}' \
+ | T49_API_TOKEN=YOUR_API_KEY node packages/mcp/dist/index.js
# Test the hosted endpoint
curl -X POST https://mcp.terminal49.com \
diff --git a/packages/mcp/README.md b/packages/mcp/README.md
index 16675dfe..f44fd6b4 100644
--- a/packages/mcp/README.md
+++ b/packages/mcp/README.md
@@ -2,6 +2,8 @@
**Vercel-native** Model Context Protocol server for Terminal49's API, built with TypeScript and the official MCP SDK.
+`@terminal49/mcp` is a private workspace in this repository. Connect a client to the hosted server at `https://mcp.terminal49.com` (Streamable HTTP). OAuth 2.1 needs no API key: the client discovers `https://auth.terminal49.com` and opens a browser sign-in. Clients that can't run that flow send `Authorization: Token YOUR_API_KEY`. Use the `Token` scheme for API keys. The `Bearer` scheme is used for OAuth access tokens. A local stdio process reads `T49_API_TOKEN` instead. Build steps are in [Local Development](#local-development).
+
## 🚀 Quick Deploy to Vercel
[](https://vercel.com/new/clone?repository-url=https://github.com/Terminal49/API)
@@ -84,7 +86,7 @@ Tool results separate the human-readable answer from agent-steering metadata. Th
- Type-safe Zod schemas for all tool inputs
- Cleaner, maintainable code (71% code reduction in HTTP handler)
- **MCP SDK**: @modelcontextprotocol/sdk ^1.29.0
-- **Terminal49 SDK**: @terminal49/sdk 0.2.0
+- **Terminal49 SDK**: @terminal49/sdk 0.6.0
#### ✅ Production Transport Support
- **HTTP (streamable)**: `POST /api/mcp` - stateless, JSON responses
@@ -125,11 +127,11 @@ Tool results separate the human-readable answer from agent-steering metadata. Th
└── package.json
```
-MCP uses published `@terminal49/sdk` by default, with optional local override for contributors.
+The MCP server depends on the workspace package `@terminal49/sdk`. Build that package before you build `packages/mcp`.
**Transport:**
- **HTTP**: Vercel serverless function at `/api/mcp` (for hosted use)
-- **stdio**: Local binary for Claude Desktop (run via `npm run mcp:stdio`)
+- **stdio**: Local process for Claude Desktop (`node packages/mcp/dist/index.js` after the build in [Local Development](#local-development))
---
@@ -190,47 +192,45 @@ namespace.
---
+
+
## 🛠️ Local Development
### Prerequisites
-- Node.js 24.x
-- Terminal49 API token ([get yours here](https://app.terminal49.com/developers/api-keys))
-### Setup
+- Node.js 24.22.1 or a newer Node 24 release (`.tool-versions` pins `24.22.1`)
+- A Terminal49 API key ([create one](https://app.terminal49.com/developers/api-keys)) for tool calls that reach the API
-```bash
-cd packages/mcp
-npm install
-T49_SDK_SOURCE=published npm run sdk:setup
-cp .env.example .env
-# Add your T49_API_TOKEN to .env
-```
+### Setup
-Use a local SDK build during MCP development:
+`@terminal49/mcp` is a private workspace. From a clone of this repository, on Node.js 24.22.1 or a newer Node 24 release:
```bash
-cd packages/mcp
-T49_SDK_SOURCE=local npm run sdk:setup
+git clone https://github.com/Terminal49/API.git
+cd API
+npm ci
+npm run build --workspace @terminal49/sdk
+npm run build --workspace @terminal49/mcp
```
-### Run Locally
+The MCP server depends on the workspace package `@terminal49/sdk`. Build that package first, as the commands above do. The stdio entrypoint is `packages/mcp/dist/index.js`. It reads `T49_API_TOKEN` and exits if that variable is unset.
-```bash
-# Stdio mode (for Claude Desktop testing)
-npm run mcp:stdio
+### Run locally
-# Development mode with auto-reload
-npm run dev
+```bash
+T49_API_TOKEN=YOUR_API_KEY node packages/mcp/dist/index.js
```
### Test the API
-```bash
-# List tools
-echo '{"jsonrpc":"2.0","method":"tools/list","id":1}' | npm run mcp:stdio
+Smoke-test `initialize`, then `tools/list`:
-# Get container
-echo '{"jsonrpc":"2.0","method":"tools/call","params":{"name":"get_container","arguments":{"id":"123e4567-e89b-12d3-a456-426614174000"}},"id":2}' | npm run mcp:stdio
+```bash
+printf '%s\n' \
+ '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"smoke","version":"1.0"}}}' \
+ '{"jsonrpc":"2.0","method":"notifications/initialized"}' \
+ '{"jsonrpc":"2.0","id":2,"method":"tools/list"}' \
+ | T49_API_TOKEN=YOUR_API_KEY node packages/mcp/dist/index.js
```
---
diff --git a/packages/mcp/TESTING.md b/packages/mcp/TESTING.md
index bfd5d11d..df2f2539 100644
--- a/packages/mcp/TESTING.md
+++ b/packages/mcp/TESTING.md
@@ -94,25 +94,28 @@ Test with the actual Claude Desktop application.
**Setup:**
-1. **Build the server:**
+1. **Build the server** from a clone, on Node.js 24.22.1 or a newer Node 24 release:
+
```bash
- cd packages/mcp
- npm install
- npm run build
+ git clone https://github.com/Terminal49/API.git
+ cd API
+ npm ci
+ npm run build --workspace @terminal49/sdk
+ npm run build --workspace @terminal49/mcp
```
2. **Configure Claude Desktop:**
- Edit `~/Library/Application Support/Claude/claude_desktop_config.json`:
+ Edit `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS), `%APPDATA%\Claude\claude_desktop_config.json` (Windows), or `~/.config/Claude/claude_desktop_config.json` (Linux):
```json
{
"mcpServers": {
"terminal49-local": {
"command": "node",
- "args": ["/Users/dodeja/dev/t49/API/packages/mcp/dist/index.js"],
+ "args": ["/absolute/path/to/API/packages/mcp/dist/index.js"],
"env": {
- "T49_API_TOKEN": "your_token_here"
+ "T49_API_TOKEN": "YOUR_API_KEY"
}
}
}