@pipeworx/mcp-merriam-webster 0.1.0 → 0.1.1
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/.github/workflows/publish.yml +152 -0
- package/README.md +31 -6
- package/package.json +1 -1
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
name: Publish to npm
|
|
2
|
+
|
|
3
|
+
# Trusted publishing (OIDC) — NO npm token anywhere in this repo.
|
|
4
|
+
#
|
|
5
|
+
# Why this file exists: npm is withdrawing the ability for access tokens to
|
|
6
|
+
# bypass 2FA when publishing. Phase 1 (2026-07-31) already blocked token-driven
|
|
7
|
+
# MANAGEMENT operations; Phase 2 (~January 2027) removes DIRECT PUBLISHING, and
|
|
8
|
+
# when it lands no token you can create will publish this package. The
|
|
9
|
+
# replacement is trusted publishing: GitHub Actions proves this repo's identity
|
|
10
|
+
# to npm over OIDC, with no long-lived credential to leak or rotate.
|
|
11
|
+
#
|
|
12
|
+
# Provenance comes free and is why this workflow lives HERE rather than in the
|
|
13
|
+
# pipeworx-core monorepo: npm will only attach a provenance attestation when the
|
|
14
|
+
# source repo is PUBLIC, and pipeworx-core is private. This repo is public, and
|
|
15
|
+
# package.json's `repository.url` already points at it, which is the match npm
|
|
16
|
+
# checks (case-sensitive).
|
|
17
|
+
#
|
|
18
|
+
# Do NOT add `--provenance`: with trusted publishing npm generates the
|
|
19
|
+
# attestation automatically, and passing the flag is redundant.
|
|
20
|
+
#
|
|
21
|
+
# The FILENAME matters. npm's trusted-publisher config names the org, the repo
|
|
22
|
+
# and this file's name — `publish.yml`. Renaming this file silently breaks
|
|
23
|
+
# publishing for this package until someone re-runs `npm trust` against the new
|
|
24
|
+
# name. Keep it `publish.yml` across every pack repo so the bulk config loop in
|
|
25
|
+
# pipeworx-core's scripts/npm-trust-bulk.sh stays a one-liner.
|
|
26
|
+
#
|
|
27
|
+
# This file is GENERATED by pipeworx-core's scripts/publish-pack.sh from
|
|
28
|
+
# scripts/templates/publish-npm.yml. Edit it there — publish-pack.sh rebuilds
|
|
29
|
+
# this repo from scratch and force-pushes, so local edits are erased on the next
|
|
30
|
+
# publish.
|
|
31
|
+
|
|
32
|
+
on:
|
|
33
|
+
push:
|
|
34
|
+
branches: [main]
|
|
35
|
+
paths:
|
|
36
|
+
- 'package.json'
|
|
37
|
+
- 'src/**'
|
|
38
|
+
workflow_dispatch:
|
|
39
|
+
|
|
40
|
+
permissions:
|
|
41
|
+
id-token: write # REQUIRED: lets Actions mint the OIDC token npm authenticates
|
|
42
|
+
contents: read
|
|
43
|
+
|
|
44
|
+
jobs:
|
|
45
|
+
publish:
|
|
46
|
+
runs-on: ubuntu-latest # must be GitHub-HOSTED; self-hosted runners are unsupported
|
|
47
|
+
steps:
|
|
48
|
+
- uses: actions/checkout@v4
|
|
49
|
+
|
|
50
|
+
- uses: actions/setup-node@v4
|
|
51
|
+
with:
|
|
52
|
+
node-version: 22 # trusted publishing needs Node >= 22.14.0
|
|
53
|
+
# Deliberately NO `registry-url:` — that option exists to inject a token
|
|
54
|
+
# into an .npmrc, writes a literal `_authToken=${NODE_AUTH_TOKEN}` line,
|
|
55
|
+
# and would trip the credential assertion below. npm publish already
|
|
56
|
+
# defaults to registry.npmjs.org.
|
|
57
|
+
|
|
58
|
+
- name: Upgrade npm to a trusted-publishing-capable version
|
|
59
|
+
# The runner image's bundled npm lags. Trusted publishing needs npm
|
|
60
|
+
# >= 11.5.1; installing `latest` rather than a pinned version keeps this
|
|
61
|
+
# from silently rotting, and the assertion below fails loudly rather
|
|
62
|
+
# than falling through to a publish that cannot authenticate.
|
|
63
|
+
run: |
|
|
64
|
+
set -euo pipefail
|
|
65
|
+
npm install -g npm@latest
|
|
66
|
+
v=$(npm --version)
|
|
67
|
+
echo "npm $v"
|
|
68
|
+
node -e 'const v=process.argv[1].split("-")[0].split(".").map(Number);
|
|
69
|
+
const min=[11,5,1];
|
|
70
|
+
for (let i=0;i<3;i++){ if(v[i]>min[i]) break; if(v[i]<min[i]){
|
|
71
|
+
console.error(`npm ${process.argv[1]} is below the 11.5.1 trusted-publishing floor`);
|
|
72
|
+
process.exit(1); } }' "$v"
|
|
73
|
+
|
|
74
|
+
- name: Assert no npm token is present
|
|
75
|
+
# The whole point of this workflow is that it publishes with NO
|
|
76
|
+
# credential. If a token ever appears, a publish could succeed for the
|
|
77
|
+
# wrong reason and hide a broken OIDC config until Phase 2 removes the
|
|
78
|
+
# token fallback and every pack breaks at once. Fail loudly instead.
|
|
79
|
+
run: |
|
|
80
|
+
set -euo pipefail
|
|
81
|
+
if [ -n "${NODE_AUTH_TOKEN:-}" ] || [ -n "${NPM_TOKEN:-}" ]; then
|
|
82
|
+
echo "::error::an npm token is in the environment; this workflow must publish over OIDC only"
|
|
83
|
+
exit 1
|
|
84
|
+
fi
|
|
85
|
+
tok=$(npm config get //registry.npmjs.org/:_authToken 2>/dev/null || echo "undefined")
|
|
86
|
+
if [ "$tok" != "undefined" ] && [ -n "$tok" ]; then
|
|
87
|
+
echo "::error::npm config carries an _authToken; refusing to publish"
|
|
88
|
+
exit 1
|
|
89
|
+
fi
|
|
90
|
+
echo "no npm credential present — publishing over OIDC"
|
|
91
|
+
|
|
92
|
+
- name: Skip if this version is already published
|
|
93
|
+
id: check
|
|
94
|
+
run: |
|
|
95
|
+
set -euo pipefail
|
|
96
|
+
name=$(node -p "require('./package.json').name")
|
|
97
|
+
version=$(node -p "require('./package.json').version")
|
|
98
|
+
published=$(npm view "$name" version 2>/dev/null || echo "")
|
|
99
|
+
echo "name=$name" >> "$GITHUB_OUTPUT"
|
|
100
|
+
echo "version=$version" >> "$GITHUB_OUTPUT"
|
|
101
|
+
if [ "$published" = "$version" ]; then
|
|
102
|
+
# Not an error: most pushes here are README/metadata refreshes from
|
|
103
|
+
# publish-pack.sh, which force-pushes the whole repo. Publishing is
|
|
104
|
+
# the exception, so a same-version push is the normal case.
|
|
105
|
+
echo "skip=true" >> "$GITHUB_OUTPUT"
|
|
106
|
+
echo "::notice::$name@$version already published — nothing to do"
|
|
107
|
+
else
|
|
108
|
+
echo "skip=false" >> "$GITHUB_OUTPUT"
|
|
109
|
+
echo "::notice::publishing $name@$version (registry has ${published:-none})"
|
|
110
|
+
fi
|
|
111
|
+
|
|
112
|
+
- name: Publish
|
|
113
|
+
if: steps.check.outputs.skip == 'false'
|
|
114
|
+
# Do NOT add --provenance: with trusted publishing npm generates the
|
|
115
|
+
# attestation automatically.
|
|
116
|
+
#
|
|
117
|
+
# The error translation below is not decoration. When no trusted
|
|
118
|
+
# publisher is configured for this package, npm does not say so — it
|
|
119
|
+
# returns a generic `ENEEDAUTH / You need to authorize this machine
|
|
120
|
+
# using npm login`, which reads exactly like a forgotten credential and
|
|
121
|
+
# sends you looking for a token. There is no token to find; that is the
|
|
122
|
+
# point. The ENEEDAUTH text itself was seen live in mcp-opentargets run
|
|
123
|
+
# 33261239541 — but note that run executed a plain `npm publish`, so the
|
|
124
|
+
# capture-and-translate below was NOT what produced it.
|
|
125
|
+
#
|
|
126
|
+
# `set -e` IS ON here: GitHub's default `run:` shell is `bash -e {0}` —
|
|
127
|
+
# visible in that run's own step header — and `set -uo pipefail` does not
|
|
128
|
+
# clear it. A bare `out=$(npm publish ...)` therefore aborts the step AT
|
|
129
|
+
# THE ASSIGNMENT the instant publish fails, swallowing npm's output AND
|
|
130
|
+
# skipping the translation, leaving a red step with an EMPTY log. Since
|
|
131
|
+
# every pack fails this way until its trusted publisher exists, that is
|
|
132
|
+
# the common path, not the edge case. `|| rc=$?` keeps the failure
|
|
133
|
+
# in-band. Do not "simplify" it back to a bare assignment.
|
|
134
|
+
run: |
|
|
135
|
+
set -uo pipefail
|
|
136
|
+
out=$(npm publish --access public 2>&1) && rc=0 || rc=$?
|
|
137
|
+
echo "$out"
|
|
138
|
+
if [ $rc -ne 0 ] && echo "$out" | grep -q 'ENEEDAUTH'; then
|
|
139
|
+
# npm-trust-bulk.sh --only matches pack SLUGS, and the repo name is
|
|
140
|
+
# mcp-<slug> — strip the prefix or the suggested command matches
|
|
141
|
+
# nothing (seen live: "--only mcp-csv" → "matched no outstanding
|
|
142
|
+
# published pack").
|
|
143
|
+
repo='${{ github.event.repository.name }}'
|
|
144
|
+
echo "::error::npm returned ENEEDAUTH. This almost certainly means no trusted publisher is configured for this package yet, NOT that a token is missing — this workflow publishes over OIDC and deliberately has no credential. Fix: from pipeworx-core, npm login (interactive, 2FA) then ./scripts/npm-trust-bulk.sh --only ${repo#mcp-}. See docs/npm-trusted-publishing.md."
|
|
145
|
+
fi
|
|
146
|
+
exit $rc
|
|
147
|
+
|
|
148
|
+
- name: Report
|
|
149
|
+
if: steps.check.outputs.skip == 'false'
|
|
150
|
+
run: |
|
|
151
|
+
echo "published ${{ steps.check.outputs.name }}@${{ steps.check.outputs.version }}"
|
|
152
|
+
echo "verify: npm view ${{ steps.check.outputs.name }} dist.attestations"
|
package/README.md
CHANGED
|
@@ -2,12 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
Merriam-Webster MCP — wraps the Merriam-Webster Collegiate Dictionary and
|
|
4
4
|
|
|
5
|
-
Part of [Pipeworx](https://pipeworx.io) — an MCP gateway connecting AI agents to
|
|
5
|
+
Part of [Pipeworx](https://pipeworx.io) — an MCP gateway connecting AI agents to 1481+ live data sources.
|
|
6
6
|
|
|
7
7
|
## Tools
|
|
8
8
|
|
|
9
9
|
| Tool | Description |
|
|
10
10
|
|------|-------------|
|
|
11
|
+
| `define` | Look up a word in the Merriam-Webster dictionary — the authoritative American English dictionary. Returns word definitions (short definitions), part of speech (noun, verb, adjective, etc.), pronunciation, and etymology (word origin). When the word is not found, returns close spelling suggestions instead. Example: define({ word: "ephemeral" }) |
|
|
12
|
+
| `thesaurus` | Look up a word in the Merriam-Webster thesaurus — the authoritative American English thesaurus. Returns synonyms and antonyms grouped by sense, along with part of speech (noun, verb, adjective, etc.) and short definitions. When the word is not found, returns close spelling suggestions instead. Example: thesaurus({ word: "happy" }) |
|
|
11
13
|
|
|
12
14
|
## Quick Start
|
|
13
15
|
|
|
@@ -16,14 +18,32 @@ Add to your MCP client (Claude Desktop, Cursor, Windsurf, etc.):
|
|
|
16
18
|
```json
|
|
17
19
|
{
|
|
18
20
|
"mcpServers": {
|
|
19
|
-
"
|
|
20
|
-
"url": "https://gateway.pipeworx.io/
|
|
21
|
+
"merriam_webster": {
|
|
22
|
+
"url": "https://gateway.pipeworx.io/merriam_webster/mcp"
|
|
21
23
|
}
|
|
22
24
|
}
|
|
23
25
|
}
|
|
24
26
|
```
|
|
25
27
|
|
|
26
|
-
|
|
28
|
+
### What this endpoint actually serves
|
|
29
|
+
|
|
30
|
+
`tools/list` at `https://gateway.pipeworx.io/merriam_webster/mcp` returns the tools in the table
|
|
31
|
+
above **plus the shared Pipeworx meta-tools** — `ask_pipeworx`,
|
|
32
|
+
`discover_tools`, `search_within`, `remember`/`recall` and the rest of the
|
|
33
|
+
gateway-wide set. So the tool count you see is larger than this table: a
|
|
34
|
+
single-pack endpoint currently lists roughly 30 shared tools alongside the
|
|
35
|
+
pack's own. The connection's `initialize` response states its exact scope, and
|
|
36
|
+
is the authoritative answer for a given day.
|
|
37
|
+
|
|
38
|
+
This is deliberate, not multiplexing by accident. The meta-tools are what let a
|
|
39
|
+
scoped connection answer a question this pack does not cover — via
|
|
40
|
+
`ask_pipeworx`, which routes across the whole catalog — without you adding a
|
|
41
|
+
second MCP server. There is currently no way to mount a pack endpoint without
|
|
42
|
+
them; if the extra schemas cost you more context than the routing is worth,
|
|
43
|
+
connect to the full gateway once rather than to several pack endpoints.
|
|
44
|
+
|
|
45
|
+
Or connect to the full Pipeworx gateway to get every pack's tools listed
|
|
46
|
+
directly, instead of just this one's:
|
|
27
47
|
|
|
28
48
|
```json
|
|
29
49
|
{
|
|
@@ -35,9 +55,14 @@ Or connect to the full Pipeworx gateway for access to all 764+ data sources:
|
|
|
35
55
|
}
|
|
36
56
|
```
|
|
37
57
|
|
|
58
|
+
Both URLs reach the same gateway and the same 1481+ data sources. The
|
|
59
|
+
only difference is which pack's tools are listed **directly**; `ask_pipeworx`
|
|
60
|
+
reaches all of them from either one.
|
|
61
|
+
|
|
38
62
|
## Using with ask_pipeworx
|
|
39
63
|
|
|
40
|
-
Instead of calling tools directly, you can ask questions in plain English
|
|
64
|
+
Instead of calling tools directly, you can ask questions in plain English —
|
|
65
|
+
this works on the pack endpoint above as well as on the full gateway:
|
|
41
66
|
|
|
42
67
|
```
|
|
43
68
|
ask_pipeworx({ question: "your question about Merriam Webster data" })
|
|
@@ -47,7 +72,7 @@ The gateway picks the right tool and fills the arguments automatically.
|
|
|
47
72
|
|
|
48
73
|
## More
|
|
49
74
|
|
|
50
|
-
- [
|
|
75
|
+
- [Docs and guides](https://pipeworx.io/docs)
|
|
51
76
|
- [pipeworx.io](https://pipeworx.io)
|
|
52
77
|
|
|
53
78
|
## License
|