@plurnk/plurnk-mcp 1.7.0 → 1.9.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 CHANGED
@@ -5,6 +5,15 @@
5
5
  PLURNK_MCP_CONNECT_TIMEOUT=30000
6
6
  PLURNK_MCP_REQUEST_TIMEOUT=86400000
7
7
 
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
+
8
17
  # Each configured server contributes its enabled `[server] (tool)` rows and server:// resources.
9
18
  #
10
19
  # Streamable HTTP:
@@ -19,3 +28,19 @@ PLURNK_MCP_REQUEST_TIMEOUT=86400000
19
28
  # PLURNK_MCP_atlas_ARGS=["/absolute/path/to/atlas-server.mjs"]
20
29
  # PLURNK_MCP_atlas_CWD=/absolute/working/directory
21
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
@@ -5,16 +5,21 @@ module for [Plurnk](https://github.com/plurnk/plurnk-service). It projects
5
5
  trusted MCP servers through Plurnk's existing executor, resource, proposal,
6
6
  entry, Problem, lifecycle, and AG-UI contracts.
7
7
 
8
- The module accepts only protocol revision `2026-07-28`. A legacy endpoint is
9
- rejected with a `protocol-revision-unsupported` Problem that names the required
10
- revision and `server/discover`; Plurnk does not negotiate a downgrade.
11
-
12
- ## Attach a server
13
-
14
- Service environment variables provide optional defaults for every workspace.
15
- Users can also attach, replace, reconnect, or detach a server in one workspace
16
- without restarting the daemon. An existing AG-UI connection sends the ordinary
17
- management-action form under `forwardedProps.plurnk.action`:
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 Worker servers
17
+
18
+ Service environment variables provide available servers for every Worker;
19
+ `PLURNK_MCP_ENABLED` selects the exact cold-enabled subset. Users can add,
20
+ enable, disable, or remove one Worker's servers without restarting the daemon. An
21
+ existing AG-UI connection sends the ordinary management-action form under
22
+ `forwardedProps.plurnk.action`:
18
23
 
19
24
  ```json
20
25
  {
@@ -22,8 +27,9 @@ management-action form under `forwardedProps.plurnk.action`:
22
27
  "plurnk": {
23
28
  "workspace": "example",
24
29
  "action": {
25
- "kind": "workspace.mcp.attach",
26
- "server": {
30
+ "kind": "worker.mcp.add",
31
+ "alias": "project",
32
+ "definition": {
27
33
  "name": "project",
28
34
  "transport": "stdio",
29
35
  "command": "/opt/mcp/current-server",
@@ -39,27 +45,78 @@ management-action form under `forwardedProps.plurnk.action`:
39
45
  ```
40
46
 
41
47
  The standard `plurnk.action.result` event reports success or exact RFC 9457
42
- Problem Details. The definition is durable and workspace-shared; symbolic
48
+ Problem Details. The definition is durable and Worker-private; symbolic
43
49
  environment references remain unexpanded at rest.
44
50
 
45
- Available workspace actions are:
51
+ MCP is one family of Worker Functionality; the common lifecycle actions are
52
+ published by the coordinator and the two continuations by this module:
46
53
 
47
54
  | Action | Parameters |
48
55
  |---|---|
49
- | `workspace.mcp.list` | none |
50
- | `workspace.mcp.attach` | `server` definition |
51
- | `workspace.mcp.replace` | `server` definition with the existing name |
52
- | `workspace.mcp.detach` | `name` |
53
- | `workspace.mcp.reconnect` | `name` |
54
- | `workspace.mcp.oauth.complete` | `name`, complete `callbackUrl` |
55
- | `workspace.mcp.complete` | `server`, completion `ref` and `argument`; optional `context` |
56
+ | `worker.mcp.list` | — |
57
+ | `worker.mcp.discover` | optional `query`, `source` (URL or command line), `configuration` (a client's `PLURNK_MCP_*` overlay) |
58
+ | `worker.mcp.add` | optional `alias` (must equal the definition's `name`), `definition: McpServerDefinition` |
59
+ | `worker.mcp.enable` / `disable` / `remove` | `alias` |
60
+ | `worker.mcp.oauth.complete` | `alias`, complete `callbackUrl` |
61
+ | `worker.mcp.complete` | `server`, completion `ref` and `argument`; optional `context` |
62
+
63
+ The model manages the same family through `EXEC [mcp] (list|discover|add|enable|disable|remove)`.
56
64
 
57
65
  The owning [specification](./SPEC.md) defines the complete action and server
58
66
  definition contracts.
59
67
 
68
+ Client and project configuration can specialize a cold service definition
69
+ without copying it or restarting the daemon. For example, a service catalog
70
+ can provide the executable while one project's `.env` supplies its identity:
71
+
72
+ ```text
73
+ # $XDG_CONFIG_HOME/plurnk/.env, read by the service
74
+ PLURNK_MCP_GITEA=/usr/local/bin/possumtech-gitea-mcp
75
+ PLURNK_MCP_ENABLED=[]
76
+
77
+ # <project>/.env, read by the client
78
+ PLURNK_MCP_GITEA_ARGS=["plurnk_pk"]
79
+ ```
80
+
81
+ The client carries its raw declarations while listing and enabling. Listing is
82
+ inert. `/mcp enable gitea` (or `plurnk mcp enable gitea` in a bound conversation)
83
+ composes service, durable worker, client, and optional command-file fields
84
+ in that order, prepares the connection, then persists the complete unexpanded
85
+ worker specialization. Arrays and maps replace rather than append or merge.
86
+
87
+ ## Demo fixtures
88
+
89
+ Web discovery is an ordinary MCP attachment ({§web-search-retrieval}); the demo
90
+ tier exercises search through a documented fixture rather than an owned
91
+ runtime. Two service-owned definitions are permitted to participate in demos
92
+ of MCP and model behavior — Gitea (above) and Brave Search:
93
+
94
+ ```text
95
+ # $XDG_CONFIG_HOME/plurnk/.env, read by the service — demo fixtures; never default-enabled
96
+ PLURNK_MCP_BRAVE=npx
97
+ PLURNK_MCP_BRAVE_ARGS=["-y","@brave/brave-search-mcp-server@2.1.0"]
98
+ PLURNK_MCP_BRAVE_ENV={"BRAVE_API_KEY":"${BRAVE_API_KEY}"}
99
+ PLURNK_MCP_BRAVE_TOOLS=["brave_web_search","brave_news_search"]
100
+ PLURNK_MCP_BRAVE_READ=["brave_web_search","brave_news_search"]
101
+ PLURNK_MCP_ENABLED=[]
102
+ ```
103
+
104
+ The credential is one symbolic reference — the authoritative `BRAVE_API_KEY`
105
+ environment value is expanded only while preparing the connection, never
106
+ copied. The fixture admits exactly the web/news search tools and classifies
107
+ them read-only; the rest of the vendor catalog is not admitted.
108
+
109
+ **Pinned release and revision.** `@brave/brave-search-mcp-server@2.1.0`
110
+ (stdio) pins `@modelcontextprotocol/sdk@1.29.0`, whose latest protocol
111
+ revision is `2025-11-25` and which does not implement `server/discover`. The
112
+ host negotiates-and-degrades ({§mcp-authority}), so the fixture connects at
113
+ `2025-11-25` with the standard tool surface — verified live: the demo story
114
+ `{§web-search-retrieval}` researched through the real Brave MCP tool and
115
+ answered from it.
116
+
60
117
  ## Service defaults
61
118
 
62
- One `PLURNK_MCP_<server>` variable declares each default server. Its suffix
119
+ One `PLURNK_MCP_<server>` variable declares each available server. Its suffix
63
120
  case-folds to an `[a-z][a-z0-9-]*` executor and URI-authority name.
64
121
 
65
122
  Streamable HTTP:
@@ -69,6 +126,7 @@ PLURNK_MCP_github=https://example.test/mcp
69
126
  PLURNK_MCP_github_BEARER=${GITHUB_TOKEN}
70
127
  PLURNK_MCP_github_TOOLS=["issue_read","issue_search"]
71
128
  PLURNK_MCP_github_READ=["issue_read","issue_search"]
129
+ PLURNK_MCP_ENABLED=["github"]
72
130
  ```
73
131
 
74
132
  Stdio:
@@ -98,13 +156,13 @@ Portable timeouts and complete examples live in [`.env.defaults`](./.env.default
98
156
 
99
157
  | MCP surface | Plurnk surface |
100
158
  |---|---|
101
- | Enabled tool | Exact Registered Tools row and `## EXEC0 [server] (tool)` |
102
- | Tool schemas | `worker://plurnk/docs/<server>.md` |
159
+ | Server tools | `worker://~/_plurnk/tools/<server>.md` family summary |
160
+ | Enabled tool | Exact `worker://~/_plurnk/tools/<server>/<encoded-tool>.md` document and `## EXEC0 [server] (tool)` |
103
161
  | Resource catalog | `server:///` or `server:///resources` |
104
162
  | Resource | `server:///resources/<encoded-uri>` through ordinary `FIND` and `READ` |
105
163
  | Prompt catalog | `server:///prompts` |
106
164
  | Prompt retrieval | `server:///prompts/<encoded-name>?argument=value` through ordinary `READ` |
107
- | Completion | Client-owned `workspace.mcp.complete` action |
165
+ | Completion | Client-owned `worker.mcp.complete` action |
108
166
 
109
167
  Tool results, resource bodies, prompt messages, and failures become ordinary
110
168
  Plurnk entries and channels. Disabled tools appear in neither teaching nor
@@ -119,10 +177,10 @@ client.
119
177
  ## Authorization
120
178
 
121
179
  HTTP definitions support bearer references, client credentials, and
122
- interactive OAuth. Stdio never receives OAuth. Interactive attachment returns
180
+ interactive OAuth. Stdio never receives OAuth. Interactive add or enable returns
123
181
  `{ "status": 202, "authorization": { "url": "..." } }` without publishing a
124
182
  partial server. After the user completes that URL, the client submits its
125
- complete callback URL through `workspace.mcp.oauth.complete`. PKCE, issuer and
183
+ complete callback URL through `worker.mcp.oauth.complete`. PKCE, issuer and
126
184
  resource validation, refresh, scope escalation, and credentials remain inside
127
185
  the host connection.
128
186