From 8d76a5ee6bae4fd8ee246d777836d930f5bc7c0a Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Fri, 30 Oct 2026 19:35:45 +0000 Subject: [PATCH 1/3] fix: set the MCP registry websiteUrl to the docs home Point server.json at https://terminal49.com/docs/mcp/home and keep version 1.1.0. Co-authored-by: Akshay Dodeja --- server.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server.json b/server.json index bfc73af8..6ee82f1a 100644 --- a/server.json +++ b/server.json @@ -4,7 +4,7 @@ "title": "Terminal49", "description": "Live ocean container and shipment tracking with ETAs, holds, fees, and last free days.", "version": "1.1.0", - "websiteUrl": "https://terminal49.com/ai", + "websiteUrl": "https://terminal49.com/docs/mcp/home", "repository": { "url": "https://github.com/Terminal49/API", "source": "github", From d0bbf85656d70d948f2e9ec2633f0b91902e2722 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Fri, 30 Oct 2026 19:35:45 +0000 Subject: [PATCH 2/3] chore: publish the MCP registry entry with GitHub OIDC Add a workflow that verifies mcp-publisher v1.8.1 and publishes server.json on main. Co-authored-by: Akshay Dodeja --- .github/workflows/publish-mcp.yml | 61 +++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 .github/workflows/publish-mcp.yml diff --git a/.github/workflows/publish-mcp.yml b/.github/workflows/publish-mcp.yml new file mode 100644 index 00000000..3219a907 --- /dev/null +++ b/.github/workflows/publish-mcp.yml @@ -0,0 +1,61 @@ +name: Publish to MCP Registry + +# Publishes the root server.json to https://registry.modelcontextprotocol.io. +# Publisher install and Sigstore verification follow the official guide: +# https://github.com/modelcontextprotocol/registry/blob/main/docs/modelcontextprotocol-io/github-actions.mdx +# When upgrading, set MCP_PUBLISHER_VERSION to one release tag. +# Keep the download on releases/download/${MCP_PUBLISHER_VERSION}. + +on: + workflow_dispatch: + push: + branches: + - main + paths: + - server.json + +permissions: + contents: read + +jobs: + publish: + if: github.ref == 'refs/heads/main' + runs-on: ubuntu-latest + permissions: + id-token: write # Required for OIDC authentication + contents: read + env: + MCP_PUBLISHER_VERSION: v1.8.1 + + steps: + - name: Checkout code + uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5 + with: + persist-credentials: false + + - name: Install cosign + uses: sigstore/cosign-installer@6f9f17788090df1f26f669e9d70d6ae9567deba6 # v4.1.2 + + - name: Download and verify mcp-publisher + run: | + set -euo pipefail + os="$(uname -s | tr '[:upper:]' '[:lower:]')" + arch="$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/')" + archive="mcp-publisher_${os}_${arch}.tar.gz" + base_url="https://github.com/modelcontextprotocol/registry/releases/download/${MCP_PUBLISHER_VERSION}" + + curl --fail --location --silent --show-error --output "$archive" "$base_url/$archive" + curl --fail --location --silent --show-error --output "$archive.sigstore.json" "$base_url/$archive.sigstore.json" + cosign verify-blob \ + --bundle "$archive.sigstore.json" \ + --certificate-identity "https://github.com/modelcontextprotocol/registry/.github/workflows/release.yml@refs/tags/${MCP_PUBLISHER_VERSION}" \ + --certificate-oidc-issuer "https://token.actions.githubusercontent.com" \ + "$archive" + tar xzf "$archive" mcp-publisher + rm -f "$archive" "$archive.sigstore.json" + + - name: Authenticate to MCP Registry + run: ./mcp-publisher login github-oidc + + - name: Publish server to MCP Registry + run: ./mcp-publisher publish From ac89af055c504eaf6cda823c7ce7e22641722dd0 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Fri, 30 Oct 2026 19:35:46 +0000 Subject: [PATCH 3/3] docs: add the Cline install guide and registry publish steps Record packages/mcp/llms-install.md and point the MCP README at the OIDC workflow. Co-authored-by: Akshay Dodeja --- packages/mcp/README.md | 26 +++++++------ packages/mcp/llms-install.md | 73 ++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+), 11 deletions(-) create mode 100644 packages/mcp/llms-install.md diff --git a/packages/mcp/README.md b/packages/mcp/README.md index bf678728..09798f65 100644 --- a/packages/mcp/README.md +++ b/packages/mcp/README.md @@ -145,6 +145,9 @@ submission metadata are checked in at the repository root: - `server.json` — official MCP Registry metadata used for Copilot discovery - `public/store-icons/terminal49-{light,dark}.png` — 512×512 brand icons +Cline and other clients that read a marketplace install guide from the server +subfolder use `packages/mcp/llms-install.md`. + ### Verify the domain for ChatGPT OpenAI generates a unique domain-verification token during submission. Add that @@ -176,19 +179,20 @@ available for clients that support theme-specific assets. ### Publish for Copilot discovery -GitHub's Copilot registry is a curated downstream discovery surface. Publish -`server.json` to the official MCP Registry to make Terminal49 eligible for that -surface: +GitHub's Copilot registry is a curated downstream discovery surface. The root +`server.json` is the official MCP Registry entry +(`io.github.Terminal49/terminal49`). -```bash -mcp-publisher validate server.json -mcp-publisher login github -mcp-publisher publish server.json -``` +[`.github/workflows/publish-mcp.yml`](../../.github/workflows/publish-mcp.yml) +publishes that file to `https://registry.modelcontextprotocol.io`. It runs when +a push to `main` changes `server.json`, and a maintainer can start it with +`workflow_dispatch` on `main`. The job authenticates with GitHub OIDC +(`mcp-publisher login github-oidc`) and then runs `mcp-publisher publish`. The +`io.github.Terminal49` namespace is authorized for OIDC from this organization +repository, so the workflow needs no registry secret. -The publisher must authenticate as an owner of the `Terminal49` GitHub -organization because the registry name uses its `io.github.Terminal49` -namespace. +Bump `version` in `server.json` for each metadata change. The registry keeps +published versions, and a second publish of the same version is rejected. --- diff --git a/packages/mcp/llms-install.md b/packages/mcp/llms-install.md new file mode 100644 index 00000000..42b29122 --- /dev/null +++ b/packages/mcp/llms-install.md @@ -0,0 +1,73 @@ +# Installing the Terminal49 MCP server (for Cline and other AI agents) + +Terminal49 is a **hosted, remote** MCP server. There is nothing to clone, build, +or run locally, and there are **no API keys or environment variables**. The user +signs in with their own Terminal49 account through OAuth in the browser. + +- Server URL: `https://mcp.terminal49.com` +- Transport: Streamable HTTP +- Auth: OAuth 2.1 with PKCE (S256) and dynamic client registration, issued by + `https://auth.terminal49.com`. The client discovers it from the server's + `401` response (`WWW-Authenticate: resource_metadata=...`) and + `https://mcp.terminal49.com/.well-known/oauth-protected-resource`. +- Docs: https://terminal49.com/docs/mcp/home + +## Steps for Cline + +1. Do not clone this repository or run `npm install`. The server is already hosted. +2. Add this entry under `mcpServers` in Cline's MCP settings file + (`cline_mcp_settings.json`; in the IDE: MCP Servers → Configure → + Configure MCP Servers; CLI: `~/.cline/data/settings/cline_mcp_settings.json`). + Merge it with any servers already there; do not overwrite them. + + ```json + { + "mcpServers": { + "terminal49": { + "type": "streamableHttp", + "url": "https://mcp.terminal49.com", + "disabled": false, + "autoApprove": [] + } + } + } + ``` + + Alternatively, in the Cline panel open **MCP Servers → Remote Servers**, + enter the name `terminal49`, the URL `https://mcp.terminal49.com`, choose + **Streamable HTTP**, and click **Add Server**. + +3. Do **not** add an `Authorization` header and do not ask the user for an API + key or token. Leave `oauthClient` unset: the authorization server supports + dynamic client registration, so Cline registers itself. +4. When Cline reports that the server needs authorization, start the OAuth flow + (the **Authorize** / **Authenticate** action on the server). A browser window + opens at `auth.terminal49.com`. The user signs in with their Terminal49 + account and approves access. Tell the user this step needs them. +5. Verify the connection by calling the `whoami` tool. It returns the + Terminal49 account the session is scoped to. Then try a lookup such as + `search_container` with a container, booking or bill of lading number. + +If the user doesn't have a Terminal49 account, they can sign up at +https://terminal49.com. + +## What the user can ask + +- "Where is container MSCU1234567, and when is its last free day?" +- "Which of my containers have holds at the terminal?" +- "What's arriving at Long Beach this week?" +- "Start tracking bill of lading MAEU123456789." + +Lookup tools are read-only. `track_container` starts tracking a number the user +provides. Only call `set_party_role` or `set_custom_field` when the user +explicitly asks to change a record. + +## Troubleshooting + +- **401 Unauthorized:** the OAuth step hasn't been completed or the token + expired. Re-run the authorization action; do not add a manual header. +- **Transport errors:** make sure `"type": "streamableHttp"` is set. Without it + Cline defaults to the legacy SSE transport, which this server does not use. +- **A tool returns "not enabled":** some data (for example trade intelligence) + is only available on accounts that have it turned on. Call `whoami` to see + which features the account has.