Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions .github/workflows/publish-mcp.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
name: Publish to MCP Registry

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Split the tooling and documentation changes into separate commits

This commit adds the registry publishing workflow while also changing MCP documentation and registry metadata, so tooling and documentation can no longer be reviewed or reverted independently. Split these changes as required by the repository's commit policy.

AGENTS.md reference: AGENTS.md:L83-L87

Useful? React with 👍 / 👎.


# 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
26 changes: 15 additions & 11 deletions packages/mcp/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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.

---

Expand Down
73 changes: 73 additions & 0 deletions packages/mcp/llms-install.md
Original file line number Diff line number Diff line change
@@ -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`).
Comment on lines +18 to +20

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Document Cline's platform-specific config paths

For users or agents editing settings directly—especially on Windows—this step names the file but provides only the Unix-style CLI path and no macOS, Windows, or Linux IDE-extension locations. That leaves the direct-edit installation path incomplete outside the UI, despite the repository's MCP documentation standard requiring all three platform paths; add those locations or make this an explicitly UI-only workflow.

AGENTS.md reference: AGENTS.md:L60-L62

Useful? React with 👍 / 👎.

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.
2 changes: 1 addition & 1 deletion server.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
Loading