@plurnk/plurnk-mcp 1.6.1 → 1.8.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/.env.defaults +31 -4
- package/README.md +161 -42
- package/SPEC.md +486 -28
- package/dist/McpExecutor.d.ts +28 -5
- package/dist/McpExecutor.d.ts.map +1 -1
- package/dist/McpExecutor.js +144 -32
- package/dist/McpExecutor.js.map +1 -1
- package/dist/McpResources.d.ts +2 -2
- package/dist/McpResources.d.ts.map +1 -1
- package/dist/McpResources.js +114 -24
- package/dist/McpResources.js.map +1 -1
- package/dist/Module.d.ts +30 -5
- package/dist/Module.d.ts.map +1 -1
- package/dist/Module.js +857 -36
- package/dist/Module.js.map +1 -1
- package/dist/ToolPresentation.d.ts +7 -0
- package/dist/ToolPresentation.d.ts.map +1 -0
- package/dist/ToolPresentation.js +224 -0
- package/dist/ToolPresentation.js.map +1 -0
- package/dist/capabilityMatrix.d.ts +23 -0
- package/dist/capabilityMatrix.d.ts.map +1 -0
- package/dist/capabilityMatrix.js +403 -0
- package/dist/capabilityMatrix.js.map +1 -0
- package/dist/client.d.ts +27 -8
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +537 -91
- package/dist/client.js.map +1 -1
- package/dist/config.d.ts +14 -13
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +257 -51
- package/dist/config.js.map +1 -1
- package/dist/extensionChannel.d.ts +25 -0
- package/dist/extensionChannel.d.ts.map +1 -0
- package/dist/extensionChannel.js +195 -0
- package/dist/extensionChannel.js.map +1 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/inputRequired.d.ts +36 -0
- package/dist/inputRequired.d.ts.map +1 -0
- package/dist/inputRequired.js +171 -0
- package/dist/inputRequired.js.map +1 -0
- package/dist/mcp-watchdog.mjs +106 -0
- package/dist/oauth.d.ts +28 -0
- package/dist/oauth.d.ts.map +1 -0
- package/dist/oauth.js +149 -0
- package/dist/oauth.js.map +1 -0
- package/dist/protocol.d.ts +8 -0
- package/dist/protocol.d.ts.map +1 -0
- package/dist/protocol.js +8 -0
- package/dist/protocol.js.map +1 -0
- package/dist/protocolHeaders.d.ts +4 -0
- package/dist/protocolHeaders.d.ts.map +1 -0
- package/dist/protocolHeaders.js +87 -0
- package/dist/protocolHeaders.js.map +1 -0
- package/dist/subscriptions.d.ts +15 -0
- package/dist/subscriptions.d.ts.map +1 -0
- package/dist/subscriptions.js +188 -0
- package/dist/subscriptions.js.map +1 -0
- package/dist/tasks.d.ts +19 -0
- package/dist/tasks.d.ts.map +1 -0
- package/dist/tasks.js +334 -0
- package/dist/tasks.js.map +1 -0
- package/package.json +12 -7
package/.env.defaults
CHANGED
|
@@ -5,15 +5,42 @@
|
|
|
5
5
|
PLURNK_MCP_CONNECT_TIMEOUT=30000
|
|
6
6
|
PLURNK_MCP_REQUEST_TIMEOUT=86400000
|
|
7
7
|
|
|
8
|
-
#
|
|
8
|
+
# Configured servers are available to clients. Only this exact JSON-array
|
|
9
|
+
# subset connects and becomes model-visible by default; workspaces may override it.
|
|
10
|
+
PLURNK_MCP_ENABLED=[]
|
|
11
|
+
|
|
12
|
+
# Turn 0 surveys enabled tool FAMILIES (one row per server, summary = its
|
|
13
|
+
# one-liner). Servers named here also expand their complete tool tree into
|
|
14
|
+
# the turn-0 survey:
|
|
15
|
+
# PLURNK_MCP_EXPANDED=[]
|
|
16
|
+
|
|
17
|
+
# Each configured server contributes its enabled `[server] (tool)` rows and server:// resources.
|
|
9
18
|
#
|
|
10
19
|
# Streamable HTTP:
|
|
11
20
|
# PLURNK_MCP_github=https://example.test/mcp
|
|
12
|
-
#
|
|
21
|
+
# PLURNK_MCP_github_BEARER=${GITHUB_TOKEN}
|
|
22
|
+
# PLURNK_MCP_github_TOOLS=["issue_read","issue_search"]
|
|
23
|
+
# PLURNK_MCP_github_READ=["issue_read","issue_search"]
|
|
13
24
|
#
|
|
14
|
-
# stdio: the target is one executable
|
|
15
|
-
# does not invent or interpret a shell
|
|
25
|
+
# stdio: the target is one exact executable path/name, including whitespace.
|
|
26
|
+
# Arguments are a JSON array so Plurnk does not invent or interpret a shell.
|
|
16
27
|
# PLURNK_MCP_atlas=node
|
|
17
28
|
# PLURNK_MCP_atlas_ARGS=["/absolute/path/to/atlas-server.mjs"]
|
|
18
29
|
# PLURNK_MCP_atlas_CWD=/absolute/working/directory
|
|
19
30
|
# PLURNK_MCP_atlas_ENV={"TOKEN":"${ATLAS_TOKEN}"}
|
|
31
|
+
#
|
|
32
|
+
# npx (installed-on-demand executables) — the documented Brave Search fixture,
|
|
33
|
+
# demo-tier only; credentials stay one ${NAME} reference in the operator env:
|
|
34
|
+
# PLURNK_MCP_BRAVE=npx
|
|
35
|
+
# PLURNK_MCP_BRAVE_ARGS=["-y","@brave/brave-search-mcp-server@2.1.0"]
|
|
36
|
+
# PLURNK_MCP_BRAVE_ENV={"BRAVE_API_KEY":"${BRAVE_API_KEY}"}
|
|
37
|
+
# PLURNK_MCP_BRAVE_TOOLS=["brave_web_search","brave_news_search"]
|
|
38
|
+
# PLURNK_MCP_BRAVE_READ=["brave_web_search","brave_news_search"]
|
|
39
|
+
#
|
|
40
|
+
# _SUMMARY companions are fallbacks only — declare one when the server's own
|
|
41
|
+
# summary metadata is missing, confusing, or garbage. The family row can carry
|
|
42
|
+
# its flagship invocation form directly:
|
|
43
|
+
# PLURNK_MCP_BRAVE_SUMMARY=EXEC [brave] (brave_web_search) <!-- Retrieve web results -->
|
|
44
|
+
# PLURNK_MCP_BRAVE_BRAVE_WEB_SEARCH_SUMMARY=General web search.
|
|
45
|
+
#
|
|
46
|
+
# Then list it above to make it model-visible, e.g. PLURNK_MCP_ENABLED=["brave"].
|
package/README.md
CHANGED
|
@@ -1,35 +1,128 @@
|
|
|
1
1
|
# @plurnk/plurnk-mcp
|
|
2
2
|
|
|
3
3
|
The current [Model Context Protocol](https://modelcontextprotocol.io/) host
|
|
4
|
-
module for [Plurnk](https://github.com/plurnk/plurnk-service).
|
|
4
|
+
module for [Plurnk](https://github.com/plurnk/plurnk-service). It projects
|
|
5
|
+
trusted MCP servers through Plurnk's existing executor, resource, proposal,
|
|
6
|
+
entry, Problem, lifecycle, and AG-UI contracts.
|
|
7
|
+
|
|
8
|
+
The module's own wire authority is protocol revision `2026-07-28`
|
|
9
|
+
({§mcp-authority}). Connection setup negotiates-and-degrades: a server that
|
|
10
|
+
offers the pinned revision and `server/discover` gets the complete extension
|
|
11
|
+
wire; a server the SDK negotiated below the pin is an ordinary MCP peer that
|
|
12
|
+
serves its standard surface at its own negotiated revision. Plurnk does not
|
|
13
|
+
downgrade its own extension wire, but it does not reject an older supported
|
|
14
|
+
revision.
|
|
15
|
+
|
|
16
|
+
## Manage workspace servers
|
|
17
|
+
|
|
18
|
+
Service environment variables provide available servers for every workspace;
|
|
19
|
+
`PLURNK_MCP_ENABLED` selects the exact cold-enabled subset. Users can add,
|
|
20
|
+
enable, disable, or remove workspace servers without restarting the daemon. An
|
|
21
|
+
existing AG-UI connection sends the ordinary management-action form under
|
|
22
|
+
`forwardedProps.plurnk.action`:
|
|
23
|
+
|
|
24
|
+
```json
|
|
25
|
+
{
|
|
26
|
+
"forwardedProps": {
|
|
27
|
+
"plurnk": {
|
|
28
|
+
"workspace": "example",
|
|
29
|
+
"action": {
|
|
30
|
+
"kind": "workspace.mcp.add",
|
|
31
|
+
"alias": "project",
|
|
32
|
+
"target": "/opt/mcp/current-server",
|
|
33
|
+
"options": {
|
|
34
|
+
"args": ["--stdio"],
|
|
35
|
+
"env": { "PROJECT_TOKEN": "${PROJECT_TOKEN}" },
|
|
36
|
+
"tools": ["issue_read", "issue_write"],
|
|
37
|
+
"read": ["issue_read"]
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
The standard `plurnk.action.result` event reports success or exact RFC 9457
|
|
46
|
+
Problem Details. The definition is durable and workspace-shared; symbolic
|
|
47
|
+
environment references remain unexpanded at rest.
|
|
5
48
|
|
|
6
|
-
|
|
7
|
-
authority:
|
|
49
|
+
Available workspace actions are:
|
|
8
50
|
|
|
9
|
-
|
|
10
|
-
|
|
51
|
+
| Action | Parameters |
|
|
52
|
+
|---|---|
|
|
53
|
+
| `workspace.mcp.list` | optional client `overlay` |
|
|
54
|
+
| `workspace.mcp.add` | `alias`, `target`; optional `options` |
|
|
55
|
+
| `workspace.mcp.enable` | `alias`; optional client `overlay` and explicit `options` |
|
|
56
|
+
| `workspace.mcp.disable` | `alias` |
|
|
57
|
+
| `workspace.mcp.remove` | `alias` |
|
|
58
|
+
| `workspace.mcp.oauth.complete` | `alias`, complete `callbackUrl` |
|
|
59
|
+
| `workspace.mcp.complete` | `server`, completion `ref` and `argument`; optional `context` |
|
|
11
60
|
|
|
12
|
-
|
|
13
|
-
|
|
61
|
+
The owning [specification](./SPEC.md) defines the complete action and server
|
|
62
|
+
definition contracts.
|
|
14
63
|
|
|
15
|
-
|
|
64
|
+
Client and project configuration can specialize a cold service definition
|
|
65
|
+
without copying it or restarting the daemon. For example, a service catalog
|
|
66
|
+
can provide the executable while one project's `.env` supplies its identity:
|
|
16
67
|
|
|
17
|
-
|
|
68
|
+
```text
|
|
69
|
+
# $XDG_CONFIG_HOME/plurnk/.env, read by the service
|
|
70
|
+
PLURNK_MCP_GITEA=/usr/local/bin/possumtech-gitea-mcp
|
|
71
|
+
PLURNK_MCP_ENABLED=[]
|
|
72
|
+
|
|
73
|
+
# <project>/.env, read by the client
|
|
74
|
+
PLURNK_MCP_GITEA_ARGS=["plurnk_pk"]
|
|
18
75
|
```
|
|
19
76
|
|
|
20
|
-
The
|
|
21
|
-
|
|
77
|
+
The client carries its raw declarations while listing and enabling. Listing is
|
|
78
|
+
inert. `/mcp enable gitea` (or `plurnk mcp enable gitea` in a named workspace)
|
|
79
|
+
composes service, durable workspace, client, and optional command-file fields
|
|
80
|
+
in that order, prepares the connection, then persists the complete unexpanded
|
|
81
|
+
workspace specialization. Arrays and maps replace rather than append or merge.
|
|
82
|
+
|
|
83
|
+
## Demo fixtures
|
|
84
|
+
|
|
85
|
+
Web discovery is an ordinary MCP attachment ({§web-search-retrieval}); the demo
|
|
86
|
+
tier exercises search through a documented fixture rather than an owned
|
|
87
|
+
runtime. Two service-owned definitions are permitted to participate in demos
|
|
88
|
+
of MCP and model behavior — Gitea (above) and Brave Search:
|
|
89
|
+
|
|
90
|
+
```text
|
|
91
|
+
# $XDG_CONFIG_HOME/plurnk/.env, read by the service — demo fixtures; never default-enabled
|
|
92
|
+
PLURNK_MCP_BRAVE=npx
|
|
93
|
+
PLURNK_MCP_BRAVE_ARGS=["-y","@brave/brave-search-mcp-server@2.1.0"]
|
|
94
|
+
PLURNK_MCP_BRAVE_ENV={"BRAVE_API_KEY":"${BRAVE_API_KEY}"}
|
|
95
|
+
PLURNK_MCP_BRAVE_TOOLS=["brave_web_search","brave_news_search"]
|
|
96
|
+
PLURNK_MCP_BRAVE_READ=["brave_web_search","brave_news_search"]
|
|
97
|
+
PLURNK_MCP_ENABLED=[]
|
|
98
|
+
```
|
|
22
99
|
|
|
23
|
-
|
|
100
|
+
The credential is one symbolic reference — the authoritative `BRAVE_API_KEY`
|
|
101
|
+
environment value is expanded only while preparing the connection, never
|
|
102
|
+
copied. The fixture admits exactly the web/news search tools and classifies
|
|
103
|
+
them read-only; the rest of the vendor catalog is not admitted.
|
|
24
104
|
|
|
25
|
-
|
|
26
|
-
|
|
105
|
+
**Pinned release and revision.** `@brave/brave-search-mcp-server@2.1.0`
|
|
106
|
+
(stdio) pins `@modelcontextprotocol/sdk@1.29.0`, whose latest protocol
|
|
107
|
+
revision is `2025-11-25` and which does not implement `server/discover`. The
|
|
108
|
+
host negotiates-and-degrades ({§mcp-authority}), so the fixture connects at
|
|
109
|
+
`2025-11-25` with the standard tool surface — verified live: the demo story
|
|
110
|
+
`{§web-search-retrieval}` researched through the real Brave MCP tool and
|
|
111
|
+
answered from it.
|
|
112
|
+
|
|
113
|
+
## Service defaults
|
|
114
|
+
|
|
115
|
+
One `PLURNK_MCP_<server>` variable declares each available server. Its suffix
|
|
116
|
+
case-folds to an `[a-z][a-z0-9-]*` executor and URI-authority name.
|
|
27
117
|
|
|
28
118
|
Streamable HTTP:
|
|
29
119
|
|
|
30
120
|
```text
|
|
31
121
|
PLURNK_MCP_github=https://example.test/mcp
|
|
32
|
-
|
|
122
|
+
PLURNK_MCP_github_BEARER=${GITHUB_TOKEN}
|
|
123
|
+
PLURNK_MCP_github_TOOLS=["issue_read","issue_search"]
|
|
124
|
+
PLURNK_MCP_github_READ=["issue_read","issue_search"]
|
|
125
|
+
PLURNK_MCP_ENABLED=["github"]
|
|
33
126
|
```
|
|
34
127
|
|
|
35
128
|
Stdio:
|
|
@@ -41,33 +134,59 @@ PLURNK_MCP_local_CWD=/absolute/working/directory
|
|
|
41
134
|
PLURNK_MCP_local_ENV={"TOKEN":"${LOCAL_TOKEN}"}
|
|
42
135
|
```
|
|
43
136
|
|
|
44
|
-
The stdio target is
|
|
45
|
-
module never parses or invokes a
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
[
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
137
|
+
The stdio target is one exact executable path or name, including literal
|
|
138
|
+
whitespace. Arguments are a JSON array; the module never parses or invokes a
|
|
139
|
+
shell command. `${NAME}` references resolve from the daemon's inherited
|
|
140
|
+
environment only while preparing a connection.
|
|
141
|
+
|
|
142
|
+
`PLURNK_MCP_<server>_TOOLS` is an optional JSON array of exact names. Absence
|
|
143
|
+
enables every listed server tool; an array enables exactly those names; `[]`
|
|
144
|
+
enables none. `PLURNK_MCP_<server>_READ` is an exact enabled-tool subset whose
|
|
145
|
+
calls use Plurnk's `read` effect. Every other enabled tool conservatively uses
|
|
146
|
+
the proposal-gated `host` effect. Remote annotations never grant effect
|
|
147
|
+
authority.
|
|
148
|
+
|
|
149
|
+
Portable timeouts and complete examples live in [`.env.defaults`](./.env.defaults).
|
|
150
|
+
|
|
151
|
+
## Plurnk projection
|
|
152
|
+
|
|
153
|
+
| MCP surface | Plurnk surface |
|
|
154
|
+
|---|---|
|
|
155
|
+
| Server tools | `worker://plurnk/tools/<server>.md` family summary |
|
|
156
|
+
| Enabled tool | Exact `worker://plurnk/tools/<server>/<encoded-tool>.md` document and `## EXEC0 [server] (tool)` |
|
|
157
|
+
| Resource catalog | `server:///` or `server:///resources` |
|
|
158
|
+
| Resource | `server:///resources/<encoded-uri>` through ordinary `FIND` and `READ` |
|
|
159
|
+
| Prompt catalog | `server:///prompts` |
|
|
160
|
+
| Prompt retrieval | `server:///prompts/<encoded-name>?argument=value` through ordinary `READ` |
|
|
161
|
+
| Completion | Client-owned `workspace.mcp.complete` action |
|
|
162
|
+
|
|
163
|
+
Tool results, resource bodies, prompt messages, and failures become ordinary
|
|
164
|
+
Plurnk entries and channels. Disabled tools appear in neither teaching nor
|
|
165
|
+
admission. There is no MCP-specific model discovery grammar.
|
|
166
|
+
|
|
167
|
+
Current pagination, cache hints, unified subscriptions, progress,
|
|
168
|
+
cancellation, multi-round-trip input, elicitation, and negotiated Tasks remain
|
|
169
|
+
inside the owning operation. Client input uses the standard AG-UI interrupt and
|
|
170
|
+
resume lifecycle; protocol continuation state is never exposed to the model or
|
|
171
|
+
client.
|
|
172
|
+
|
|
173
|
+
## Authorization
|
|
174
|
+
|
|
175
|
+
HTTP definitions support bearer references, client credentials, and
|
|
176
|
+
interactive OAuth. Stdio never receives OAuth. Interactive add or enable returns
|
|
177
|
+
`{ "status": 202, "authorization": { "url": "..." } }` without publishing a
|
|
178
|
+
partial server. After the user completes that URL, the client submits its
|
|
179
|
+
complete callback URL through `workspace.mcp.oauth.complete`. PKCE, issuer and
|
|
180
|
+
resource validation, refresh, scope escalation, and credentials remain inside
|
|
181
|
+
the host connection.
|
|
68
182
|
|
|
69
183
|
## Verification
|
|
70
184
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
185
|
+
```sh
|
|
186
|
+
npm test -w @plurnk/plurnk-mcp
|
|
187
|
+
npm run test:mcp:dogfood -w @plurnk/plurnk-service
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
The package gate runs the exact current SDK and official conformance
|
|
191
|
+
requirements. The opt-in dogfood gate composes representative current stdio
|
|
192
|
+
and Streamable HTTP servers through the assembled daemon and AG-UI product.
|