@modootoday/pmcp 0.11.0 → 0.13.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/README.md +92 -494
- package/dist/cli.js +9307 -3930
- package/dist/{embed-BBhv3y5x.d.ts → embed-BW6AWD1e.d.ts} +1 -1
- package/dist/harness-egress-bridge.d.ts +2 -0
- package/dist/harness-egress-bridge.js +74 -0
- package/dist/harness-launch-gate.d.ts +2 -0
- package/dist/harness-launch-gate.js +1187 -0
- package/dist/harness-pane-runner.d.ts +2 -0
- package/dist/harness-pane-runner.js +118 -0
- package/dist/harness-worker.d.ts +2 -0
- package/dist/harness-worker.js +2737 -0
- package/dist/http.d.ts +3 -3
- package/dist/http.js +1 -1
- package/dist/index.d.ts +5 -5
- package/dist/index.js +1 -1
- package/dist/stdio.d.ts +1 -1
- package/dist/stdio.js +1 -1
- package/dist/tui-worker.d.ts +2 -0
- package/dist/tui-worker.js +5973 -0
- package/docs/embeddings.md +125 -0
- package/docs/hosting.md +46 -0
- package/docs/mailbox.md +59 -0
- package/docs/project-configuration.md +203 -0
- package/docs/skills.md +74 -0
- package/docs/terminal-harness.md +393 -0
- package/docs/terminal-workspace.md +116 -0
- package/package.json +3 -2
- package/dist/{server-CwWcRjqz.d.ts → server-9w4R1caM.d.ts} +4 -4
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# Embedding models
|
|
2
|
+
|
|
3
|
+
[Back to the overview](../README.md)
|
|
4
|
+
|
|
5
|
+
## Switching embedding models
|
|
6
|
+
|
|
7
|
+
List the built-in presets with `pmcp models` (or `pmcp models --json`). Select a
|
|
8
|
+
model once in your project's `pmcp.toml`; both indexing and the stdio server use
|
|
9
|
+
the same settings:
|
|
10
|
+
|
|
11
|
+
```toml
|
|
12
|
+
[embedding]
|
|
13
|
+
model = "embeddinggemma-2"
|
|
14
|
+
dimensions = 256
|
|
15
|
+
cache_dir = ".cache/pmcp/models"
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
```sh
|
|
19
|
+
pmcp index
|
|
20
|
+
pmcp serve
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Indexing explicitly downloads missing model artifacts. Serving reads only local
|
|
24
|
+
artifacts and an existing, complete index. A missing model, stale catalog or
|
|
25
|
+
incompatible vectors keeps ranking lexical and reports the reason on stderr.
|
|
26
|
+
`pmcp index --dry-run` plans work without loading a model or writing files;
|
|
27
|
+
`pmcp index --local-only` refuses downloads. Use `[embedding] enabled = false`
|
|
28
|
+
or `pmcp serve --lexical` to disable semantic ranking.
|
|
29
|
+
|
|
30
|
+
| Preset | Default precision | Supported output dimensions |
|
|
31
|
+
| --------------------- | ----------------- | --------------------------- |
|
|
32
|
+
| `e5-small` | `q8` | 384 |
|
|
33
|
+
| `embeddinggemma-300m` | `q4` | 768, 512, 256, 128 |
|
|
34
|
+
| `embeddinggemma-2` | `q4` | 768, 512, 256, 128 |
|
|
35
|
+
|
|
36
|
+
E5 remains the default. Gemma presets use qualified, pinned revisions, listed by
|
|
37
|
+
`pmcp models --json`; E5 retains its existing `main` revision for compatibility.
|
|
38
|
+
Gemma dimension reduction truncates and re-normalizes the projected embedding;
|
|
39
|
+
it reduces vector storage, not loaded model memory.
|
|
40
|
+
|
|
41
|
+
CLI flags override individual config fields: `--model`, `--dtype`,
|
|
42
|
+
`--dimensions`, `--model-revision`, `--model-path`, `--model-cache`,
|
|
43
|
+
`--query-prefix`, `--passage-prefix` and `--pooling`. Omit precision and dimensions
|
|
44
|
+
in the file when you want each model's defaults. Use `--no-config` for an
|
|
45
|
+
independent CLI selection. Config paths resolve relative to the TOML file;
|
|
46
|
+
CLI model paths resolve relative to the working directory.
|
|
47
|
+
|
|
48
|
+
Query caches also include the encoder identity, so sharing a cache between
|
|
49
|
+
same-width profiles cannot reuse another encoder's query vector. Library hosts
|
|
50
|
+
using openIntentCache must open a cache with the selected output width when
|
|
51
|
+
changing dimensions; pass the encoder's indexKey as its modelId for explicit
|
|
52
|
+
profile-scoped cache metadata.
|
|
53
|
+
|
|
54
|
+
Each model, revision, precision, output width and encoder specification has its
|
|
55
|
+
own vector identity. Switching preserves other models' indexes; switching back
|
|
56
|
+
reuses unchanged vectors. `--force` re-encodes only the selected model. A local
|
|
57
|
+
`model_path` must contain the declared revision's artifacts; change `revision`
|
|
58
|
+
and reindex after replacing them. The directory's location is not its identity.
|
|
59
|
+
|
|
60
|
+
Custom Transformers.js feature-extraction models need no source edits:
|
|
61
|
+
|
|
62
|
+
```toml
|
|
63
|
+
[embedding]
|
|
64
|
+
model = "your-organization/your-onnx-model"
|
|
65
|
+
dtype = "q8"
|
|
66
|
+
revision = "your-pinned-revision"
|
|
67
|
+
|
|
68
|
+
[embedding.encoder]
|
|
69
|
+
query_prefix = "query: "
|
|
70
|
+
passage_prefix = "passage: "
|
|
71
|
+
pooling = "mean"
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Use the model's documented prefixes and pooling (`mean` or `cls`); unknown models
|
|
75
|
+
default to unprefixed mean pooling. A native `sentence_embedding` export may use
|
|
76
|
+
`projected = true`. Explicit dimension reduction is supported for the listed
|
|
77
|
+
presets. Other architectures require compatible Transformers.js exports.
|
|
78
|
+
|
|
79
|
+
The library API shares the same presets and identity rules:
|
|
80
|
+
|
|
81
|
+
```js
|
|
82
|
+
import { loadEmbedder, prepareSearch } from "@modootoday/pmcp";
|
|
83
|
+
|
|
84
|
+
const encoder = await loadEmbedder("embeddinggemma-2", {
|
|
85
|
+
dimensions: 256,
|
|
86
|
+
modelPath: "/opt/models/embeddinggemma-2",
|
|
87
|
+
localOnly: true,
|
|
88
|
+
});
|
|
89
|
+
const search = await prepareSearch(
|
|
90
|
+
{ roots: ["node_modules"] },
|
|
91
|
+
{
|
|
92
|
+
indexPath: "node_modules/.cache/pmcp/vectors.sqlite",
|
|
93
|
+
modelId: "embeddinggemma-2",
|
|
94
|
+
dimensions: 256,
|
|
95
|
+
embedder: encoder ?? undefined,
|
|
96
|
+
},
|
|
97
|
+
);
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
HTTP hosts use these options under `semantic`; HTTP catalogs are encoded in
|
|
101
|
+
memory at startup rather than reading the CLI's persisted index. Model runtime
|
|
102
|
+
settings are passed to each loader without changing global download or cache
|
|
103
|
+
policy, so hosts can prepare different encoders in one process.
|
|
104
|
+
|
|
105
|
+
## Runtime and licence
|
|
106
|
+
|
|
107
|
+
Node.js 22 or later, or Bun 1.3 or later. Ranking is lexical until an index and
|
|
108
|
+
encoder are ready. Semantic
|
|
109
|
+
ranking (the `index` command, or the HTTP handler's `semantic` option) needs
|
|
110
|
+
`@huggingface/transformers` installed separately; it is not part of the default
|
|
111
|
+
installation. The default encoder is `Xenova/multilingual-e5-small` (MIT, about
|
|
112
|
+
130 MB), so vectors indexed with the earlier English-only default are re-encoded.
|
|
113
|
+
|
|
114
|
+
The optional encoder also supports the ONNX Community EmbeddingGemma 300M and
|
|
115
|
+
EmbeddingGemma 2 exports. It uses their projected sentence embeddings and task
|
|
116
|
+
prefixes. EmbeddingGemma 2 loads its text encoder without vision or audio models.
|
|
117
|
+
EmbeddingGemma was qualified with Transformers.js 4.3.1. Install a version
|
|
118
|
+
supporting the chosen export and keep model
|
|
119
|
+
weights outside the npm package. Regenerate document vectors when changing the
|
|
120
|
+
encoder. Quantization reduces weight storage; application RAM and latency need
|
|
121
|
+
workload measurements. EmbeddingGemma 300M uses the Gemma terms; EmbeddingGemma 2
|
|
122
|
+
is listed under Apache-2.0 in its model card.
|
|
123
|
+
|
|
124
|
+
Elastic License 2.0. See `LICENSE` and `NOTICE` for terms and dependency notices.
|
|
125
|
+
Documentation: <https://pmcp.build>.
|
package/docs/hosting.md
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Hosting a skill catalog
|
|
2
|
+
|
|
3
|
+
[Back to the overview](../README.md)
|
|
4
|
+
|
|
5
|
+
## Hosting over HTTP
|
|
6
|
+
|
|
7
|
+
`@modootoday/pmcp/http` serves the same tools and resources over streamable HTTP for a hosted
|
|
8
|
+
catalog. Tools, resources, the Skills extension and prompts all read the same per-caller,
|
|
9
|
+
tier-filtered catalog, so a file of a skill a caller cannot list cannot be read either. The
|
|
10
|
+
extension's `cacheScope` is `private` there by default (`cacheScope` overrides it), and
|
|
11
|
+
`prompts: true` turns prompts on.
|
|
12
|
+
The host owns identity: `authorize(request)` returns the caller or `undefined` (answered 401),
|
|
13
|
+
and `tiersFor(caller)` decides which tiers that caller sees (default `open` and `free`; skills
|
|
14
|
+
without a tier count as `open`). The catalog is read once; call `reload()` after deploying new
|
|
15
|
+
skill releases.
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
import { createSkillHttpHandler } from "@modootoday/pmcp/http";
|
|
19
|
+
|
|
20
|
+
const skills = createSkillHttpHandler({
|
|
21
|
+
roots: [],
|
|
22
|
+
marketplaces: ["/srv/marketplace", "/srv/marketplace-free"],
|
|
23
|
+
authorize: async (request) =>
|
|
24
|
+
verifyBearer(request.headers.get("authorization")),
|
|
25
|
+
});
|
|
26
|
+
export default { fetch: (request: Request) => skills.fetch(request) };
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
The handler checks requests before they reach MCP:
|
|
30
|
+
|
|
31
|
+
| Option | Default | Effect |
|
|
32
|
+
| ----------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
33
|
+
| `allowedOrigins` | none | A request with an `Origin` other than the server's own gets 403. Listed origins are served with CORS headers, and their preflight is answered. `"*"` admits any origin. Requests without `Origin` are not from a browser page and pass. |
|
|
34
|
+
| `publicOrigins` | none | The server's own origins as browsers see them, when a proxy ends TLS and the request URL is `http://`. Without it, a same-site page behind such a proxy gets 403. |
|
|
35
|
+
| `allowedHosts` | any | When set, a `Host` outside the list gets 403 (DNS rebinding). |
|
|
36
|
+
| `maxRequestBytes` | 1 MiB | A larger body gets 413; a declared length is refused before reading. |
|
|
37
|
+
| `rateLimit` | off | `{ perMinute }` per caller id; past it, 429 with `retry-after`. |
|
|
38
|
+
|
|
39
|
+
An MCP config (`.mcp.json`) is never served as written: every `env` and `headers` value is
|
|
40
|
+
replaced with `<redacted>`, whichever entry reaches the file, and listed digests describe
|
|
41
|
+
the redacted bytes.
|
|
42
|
+
|
|
43
|
+
Pass `semantic: { modelId: "embeddinggemma-2", cacheDir, localOnly: true }` to rank by meaning: the handler encodes
|
|
44
|
+
the catalog at start with `@huggingface/transformers` and the multilingual model, so an
|
|
45
|
+
intent in one language finds a description in another. Requests rank lexically until
|
|
46
|
+
`ready()` settles, and stay lexical when the encoder cannot load (`onError` says why).
|
package/docs/mailbox.md
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# Local mailbox
|
|
2
|
+
|
|
3
|
+
[Back to the overview](../README.md)
|
|
4
|
+
|
|
5
|
+
## Optional local mailbox
|
|
6
|
+
|
|
7
|
+
Mailbox is disabled by default. The six catalog tools stay read-only. A launcher
|
|
8
|
+
that supplies a private actor credential adds five tools: mailbox_send,
|
|
9
|
+
mailbox_inbox, mailbox_read, mailbox_ack, and mailbox_sessions. Read and ack
|
|
10
|
+
record durable receipts; peer text is data and does not authorize execution.
|
|
11
|
+
|
|
12
|
+
```sh
|
|
13
|
+
pmcp mailbox init --config ./pmcp.toml
|
|
14
|
+
pmcp mailbox actor --config ./pmcp.toml --actor reviewer --actor-file /private/reviewer.actor.json
|
|
15
|
+
pmcp serve --config ./pmcp.toml --mailbox-actor-file /private/reviewer.actor.json --mailbox-runtime codex-cli
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Initialization preserves existing configuration and creates a project UUID.
|
|
19
|
+
State defaults to XDG_STATE_HOME/pmcp/projects/<project UUID>, outside the
|
|
20
|
+
repository. Credential and binding files contain secrets: keep them private,
|
|
21
|
+
outside source control and container images. Commands do not print credentials.
|
|
22
|
+
An optional mailbox-binding-file records the current attachment for a trusted
|
|
23
|
+
launcher. Replacement requires the exact mailbox-replace-session ID; stale
|
|
24
|
+
sessions are fenced. Canonical runtimes are codex-cli, claude-code, gemini-cli,
|
|
25
|
+
grok-cli, and antigravity; the Antigravity executable is agy.
|
|
26
|
+
|
|
27
|
+
The mailbox CLI also supports send, inbox, read, ack, sessions, rotate, export,
|
|
28
|
+
backup, and restore. Actor operations accept a private actor-file or existing
|
|
29
|
+
binding-file and JSON input file. Administration requires explicit operator
|
|
30
|
+
intent. Backups and exports are sensitive. Encrypted recovery bundles are
|
|
31
|
+
available through the mailbox API; key custody belongs to the operator.
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
import { MailboxService, MailboxStore } from "@modootoday/pmcp/mailbox";
|
|
35
|
+
|
|
36
|
+
const store = await MailboxStore.open({
|
|
37
|
+
enabled: true,
|
|
38
|
+
projectId,
|
|
39
|
+
databasePath,
|
|
40
|
+
});
|
|
41
|
+
const credential = await store.registerActor("reviewer");
|
|
42
|
+
const binding = await store.attach(credential, "codex-cli");
|
|
43
|
+
const mailbox = new MailboxService(store, binding);
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Pass mailbox to createSkillServer or registerMailboxTools on an existing server.
|
|
47
|
+
For HTTP, provide mailboxFor(caller) to createSkillHttpHandler; the host resolves
|
|
48
|
+
authenticated callers to authorized bindings. Tool arguments cannot choose a
|
|
49
|
+
sender identity. The host owns attachment heartbeat and cleanup. Child actors
|
|
50
|
+
have bounded authority and may reply only to their parent. Generation changes,
|
|
51
|
+
parent expiry, and credential rotation revoke stale child authority.
|
|
52
|
+
|
|
53
|
+
The public package contains one reusable local mailbox domain. Optional owned
|
|
54
|
+
terminal supervision and explicit input delivery are provided separately by the
|
|
55
|
+
[local CLI harness](terminal-harness.md); MCP mailbox tools cannot reach those
|
|
56
|
+
execution paths. Provider credentials and approvals remain with native runtimes.
|
|
57
|
+
Organization identity, fleet policy and enterprise audit retention belong to a
|
|
58
|
+
dedicated host. Existing arbitrary terminal sessions are not captured. Elastic
|
|
59
|
+
License 2.0 and NOTICE continue to apply.
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
# Project configuration
|
|
2
|
+
|
|
3
|
+
[Back to the overview](../README.md)
|
|
4
|
+
|
|
5
|
+
## Project config
|
|
6
|
+
|
|
7
|
+
A `pmcp.toml` at or above the working directory sets the catalog once, so a
|
|
8
|
+
host entry needs no flags and works from any package in the repository:
|
|
9
|
+
|
|
10
|
+
```toml
|
|
11
|
+
[catalog]
|
|
12
|
+
workspaces = [".", "packages/*"]
|
|
13
|
+
packages = ["docs"]
|
|
14
|
+
marketplaces = ["vendor/marketplace"]
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Paths resolve against the file's directory. Keys are `roots`, `scopes`,
|
|
18
|
+
`workspaces`, `packages` and `marketplaces`, each a list mirroring the flag of
|
|
19
|
+
the same meaning; an unknown key is an error. A flag replaces the file's list
|
|
20
|
+
of its kind. `--config <file>` names another file and `--no-config` ignores it.
|
|
21
|
+
|
|
22
|
+
## Native files for each agent tool
|
|
23
|
+
|
|
24
|
+
`pmcp project` writes what Claude Code, Codex, Gemini CLI, Grok Build and
|
|
25
|
+
Antigravity read natively, from cross-tool sources under `.agents/`
|
|
26
|
+
(`skills/<name>/SKILL.md`, `agents/<name>/agent.md`, `rules/*.md`) and the rest
|
|
27
|
+
of `pmcp.toml`:
|
|
28
|
+
|
|
29
|
+
```toml
|
|
30
|
+
[targets]
|
|
31
|
+
tools = ["claude", "codex", "gemini", "grok", "antigravity"]
|
|
32
|
+
|
|
33
|
+
[skills.deploy]
|
|
34
|
+
invocation = "user" # the person starts it; the model is not offered it
|
|
35
|
+
|
|
36
|
+
[agents.reviewer.claude]
|
|
37
|
+
tools = "Read, Grep" # fields one tool reads stay out of agent.md
|
|
38
|
+
|
|
39
|
+
[rules]
|
|
40
|
+
root = "AGENTS.md"
|
|
41
|
+
|
|
42
|
+
[mcp.skills]
|
|
43
|
+
command = "node"
|
|
44
|
+
args = ["${PROJECT_ROOT}/node_modules/@modootoday/pmcp/dist/cli.js", "serve"]
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
```sh
|
|
48
|
+
pmcp project # write
|
|
49
|
+
pmcp project --check # exit 2 on drift, stale or undeclared outputs
|
|
50
|
+
pmcp project add <name> # copy a catalog skill or agent into .agents/
|
|
51
|
+
pmcp project remove <name>
|
|
52
|
+
pmcp doctor # ask each installed tool what it loads
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Rules go to `.claude/rules/<dir>/`, never the top level, because Grok Build
|
|
56
|
+
loads top-level `.claude/rules/*.md` in every session regardless of `paths:`.
|
|
57
|
+
A server that names `${PROJECT_ROOT}` is launched through `sh`, which finds
|
|
58
|
+
`pmcp.toml` at spawn time, so the generated files hold no machine's path.
|
|
59
|
+
`pmcp.lock` records what was written; a file pmcp did not write is never
|
|
60
|
+
overwritten. `doctor` calls no model: it reads `claude mcp list`,
|
|
61
|
+
`codex mcp list`, `gemini skills list`, `gemini mcp list` and
|
|
62
|
+
`grok inspect --json`, and skips a tool that is not installed.
|
|
63
|
+
|
|
64
|
+
## Unified project MCP configuration
|
|
65
|
+
|
|
66
|
+
Antigravity receives a native project plugin at .agents/plugins/pmcp-mcp with
|
|
67
|
+
plugin.json and mcp_config.json. Projection removes only lock-owned entries
|
|
68
|
+
from the earlier .agents/mcp_config.json artifact and backs up both layouts.
|
|
69
|
+
Antigravity's global mcp list does not enumerate project plugin servers;
|
|
70
|
+
validate the generated plugin with agy plugin validate.
|
|
71
|
+
Its HTTP entries use serverUrl, accepted by the installed plugin validator.
|
|
72
|
+
|
|
73
|
+
Declare each MCP server once in pmcp.toml. The projector writes the native
|
|
74
|
+
project files for all selected runtimes. A server can narrow its targets:
|
|
75
|
+
|
|
76
|
+
```toml
|
|
77
|
+
[mcp.docs]
|
|
78
|
+
url = "https://example.com/mcp"
|
|
79
|
+
|
|
80
|
+
[mcp.private-api]
|
|
81
|
+
url = "https://example.com/private-mcp"
|
|
82
|
+
targets = ["claude", "codex", "gemini", "grok"]
|
|
83
|
+
bearer_token_env_var = "PRIVATE_MCP_TOKEN"
|
|
84
|
+
header_env = { "X-Workspace" = "PRIVATE_MCP_WORKSPACE" }
|
|
85
|
+
|
|
86
|
+
[mcp.local-service]
|
|
87
|
+
command = "my-mcp-server"
|
|
88
|
+
env_vars = ["MY_SERVICE_KEY"]
|
|
89
|
+
cwd = "${PROJECT_ROOT}"
|
|
90
|
+
|
|
91
|
+
[mcp.local-service.native.codex]
|
|
92
|
+
startup_timeout_sec = 30
|
|
93
|
+
|
|
94
|
+
[mcp.local-service.native.gemini]
|
|
95
|
+
timeout = 120000
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
url means Streamable HTTP; Gemini receives httpUrl. Legacy SSE is not imported
|
|
99
|
+
as HTTP. headers contains literal nonsecret headers, header_env maps header
|
|
100
|
+
names to environment variable names, and bearer_token_env_var references a
|
|
101
|
+
token without writing its value. Each runtime retains its own OAuth session.
|
|
102
|
+
Antigravity HTTP header projection is not qualified and is rejected; explicitly
|
|
103
|
+
limit those servers to supported targets. tools maps to Gemini includeTools and
|
|
104
|
+
Codex enabled_tools; it is not a cross-runtime security boundary. Native timeout
|
|
105
|
+
options retain each runtime's documented names and units. Unknown fields fail.
|
|
106
|
+
|
|
107
|
+
Import explicitly selected native configurations. Preview is the default:
|
|
108
|
+
|
|
109
|
+
```sh
|
|
110
|
+
pmcp project import-mcp --source claude:/path/to/native.json
|
|
111
|
+
pmcp project import-mcp --source codex:/path/to/config.toml --name docs --write
|
|
112
|
+
pmcp project
|
|
113
|
+
pmcp project --check
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Repeat source and name to select multiple inputs. Conflicting aliases, missing
|
|
117
|
+
requested names, unsupported authentication fields and credential-bearing URLs
|
|
118
|
+
block import. Source contents and credential values are not printed. Sources
|
|
119
|
+
are never rewritten. Review plugin-provided servers separately to avoid
|
|
120
|
+
duplicating a server the runtime already loads.
|
|
121
|
+
|
|
122
|
+
Literal stdio environment values remain in their source file. The importer
|
|
123
|
+
stores an env_from reference containing file and an RFC 6901 JSON pointer:
|
|
124
|
+
|
|
125
|
+
```toml
|
|
126
|
+
[mcp.local-service.env_from.MY_SERVICE_KEY]
|
|
127
|
+
file = "~/.config/my-client/settings.json"
|
|
128
|
+
pointer = "/mcpServers/local-service/env/MY_SERVICE_KEY"
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
The generated entry invokes pmcp project exec-mcp for that declared server.
|
|
132
|
+
It reads only the referenced values and passes them to the child process, using
|
|
133
|
+
inherited stdio. JSON and TOML sources are supported. The source must remain
|
|
134
|
+
available; rotating its value takes effect on the next server launch. A project
|
|
135
|
+
installed CLI is referenced relative to the project; otherwise pmcp must be on
|
|
136
|
+
PATH. Configurations using env_from require this release on every runtime host.
|
|
137
|
+
|
|
138
|
+
Writes retain private backups in ~/.cache/pmcp/project-backups, outside the
|
|
139
|
+
project. Receipts record file hashes and absent paths. A conflicting unmanaged
|
|
140
|
+
native alias is refused before projection writes. The managed TOML block and
|
|
141
|
+
JSON keys preserve unrelated settings. Inspect the reported backup before
|
|
142
|
+
restoring any file that another process may have edited.
|
|
143
|
+
|
|
144
|
+
Configuration references: [Codex](https://developers.openai.com/codex/config-reference/),
|
|
145
|
+
[Claude Code](https://code.claude.com/docs/en/mcp),
|
|
146
|
+
[Gemini CLI](https://geminicli.com/docs/tools/mcp-server/),
|
|
147
|
+
and [Grok Build](https://docs.x.ai/build/features/mcp-servers).
|
|
148
|
+
|
|
149
|
+
## Operator shell guards
|
|
150
|
+
|
|
151
|
+
Declare a project-owned guard explicitly to project it into Codex, Gemini or
|
|
152
|
+
Antigravity's native hooks. Without a declaration, pmcp generates no hooks.
|
|
153
|
+
|
|
154
|
+
```toml
|
|
155
|
+
[[hooks.shell]]
|
|
156
|
+
name = "shell-command-policy"
|
|
157
|
+
command = ["node", ".agents/guards/shell-command-policy.mjs"]
|
|
158
|
+
targets = ["codex", "gemini", "antigravity"]
|
|
159
|
+
timeout_ms = 15000
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
The guard script must exist under .agents/guards/ and cannot resolve outside
|
|
163
|
+
that directory. It receives one JSON object on stdin containing runtime,
|
|
164
|
+
event=before_shell, command and cwd. It returns a JSON object with
|
|
165
|
+
decision=allow or decision=deny and an optional reason. Malformed responses,
|
|
166
|
+
nonzero exits and timeouts deny the shell call. The guard receives PATH and
|
|
167
|
+
LANG rather than the native CLI's credential environment. Non-shell tools are
|
|
168
|
+
outside this contract.
|
|
169
|
+
|
|
170
|
+
Run pmcp project to write lock-owned adapter and policy artifacts under
|
|
171
|
+
.agents/pmcp-hooks/, plus the native entries in .codex/hooks.json,
|
|
172
|
+
.gemini/settings.json and .agents/hooks.json. Peer entries are retained.
|
|
173
|
+
Edited owned hook entries refuse projection for review. Removing a declaration
|
|
174
|
+
removes its generated entries and artifacts while preserving peer settings.
|
|
175
|
+
Writes retain private backups; pmcp project --check only reports drift.
|
|
176
|
+
|
|
177
|
+
Guard, policy and adapter fingerprints bind the generated command. Changing
|
|
178
|
+
guard code requires reprojection and native Codex hook review. Generated files
|
|
179
|
+
contain no trust bypass. Grok can load Claude project hooks, so this first scope
|
|
180
|
+
does not generate a second Grok guard. Hooks do not force pmcp catalog use,
|
|
181
|
+
inject reminders or replace the runtime's execution sandbox.
|
|
182
|
+
|
|
183
|
+
## Native memory metadata
|
|
184
|
+
|
|
185
|
+
```sh
|
|
186
|
+
pmcp doctor --memory --json
|
|
187
|
+
pmcp doctor --memory --tool codex
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
This explicit operation reports selected runtimes' native memory configuration
|
|
191
|
+
and path existence. It reads no memory body, index or transcript, writes no
|
|
192
|
+
configuration, connects to no MCP server and makes no provider request.
|
|
193
|
+
Ordinary doctor output is unchanged.
|
|
194
|
+
|
|
195
|
+
The report distinguishes enabled, disabled, unknown and unsupported. Path
|
|
196
|
+
existence does not establish activation. Where native metadata cannot identify
|
|
197
|
+
a project-specific location, pathScope=base reports only the storage parent;
|
|
198
|
+
the project identifier is not guessed. Supported native home overrides are
|
|
199
|
+
respected. Codex uses its native features listing. Claude and Grok report
|
|
200
|
+
explicit user settings, with active session overrides and unverified project
|
|
201
|
+
trust left unknown. Gemini context filenames and the global GEMINI.md file
|
|
202
|
+
are separate from unexposed memory-tool activation. Antigravity trajectories
|
|
203
|
+
are not reported as a memory store. pmcp does not synchronize or inject memory.
|
package/docs/skills.md
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# Skills and MCP reference
|
|
2
|
+
|
|
3
|
+
[Back to the overview](../README.md)
|
|
4
|
+
|
|
5
|
+
## Package skills
|
|
6
|
+
|
|
7
|
+
Skills are discovered by filename, including `skills/`, `.agents/skills/`,
|
|
8
|
+
`.agent/skills/`, `.claude/skills/`, `.gemini/skills/`, `.codex/skills/`, and
|
|
9
|
+
`lib/skill/` layouts
|
|
10
|
+
within the discovery depth. A skill needs a frontmatter `description` for search.
|
|
11
|
+
|
|
12
|
+
`skill_find` accepts a problem description and returns matching skills.
|
|
13
|
+
`skill_call` opens the selected document and lists the reference, script and asset
|
|
14
|
+
files it carries, as text and as resource links. Local MCP reading requires no login.
|
|
15
|
+
|
|
16
|
+
Files keep their type, as the Agent Skills layout (`references/`, `scripts/`, `assets/`)
|
|
17
|
+
expects: `skill_read` returns text as text, images and audio as image and audio content,
|
|
18
|
+
and other binary files as an embedded resource with its media type; a file whose extension
|
|
19
|
+
names text but whose bytes are not UTF-8 goes out as a blob, so its sha256 stays exact.
|
|
20
|
+
Scripts are returned, never run: running them is the host's job, from a local copy of the
|
|
21
|
+
skill. `skill_bundle` lists every file of a skill as resource links that `resources/read`
|
|
22
|
+
returns, so a host can write the skill into a local skills directory without the bytes
|
|
23
|
+
passing through the model.
|
|
24
|
+
|
|
25
|
+
`skill_catalog`, `skill_find`, `skill_describe` and `skill_bundle` declare an
|
|
26
|
+
`outputSchema` and return `structuredContent` alongside the same JSON as text.
|
|
27
|
+
Frontmatter is read as YAML (folded and block descriptions, a BOM and CRLF are fine), and
|
|
28
|
+
`metadata` is read for every skill. Loading is lenient, as the client guide asks; what
|
|
29
|
+
breaks the specification is reported, and `pmcp validate [<skill-dir>...]` checks given
|
|
30
|
+
directories or every skill the catalog reaches (name rules and length, description and
|
|
31
|
+
compatibility length, field types, name matching the directory, duplicate names).
|
|
32
|
+
|
|
33
|
+
`metadata` keeps strings, string lists and maps of those one level down; `skill_describe`
|
|
34
|
+
reports a map as dotted keys, so `requires: {mcp, gpu-gb}` arrives as `requires.mcp` and
|
|
35
|
+
`requires.gpu-gb`. Deeper nesting is dropped.
|
|
36
|
+
|
|
37
|
+
Output schemas accept additional properties, so a field added later does not break a
|
|
38
|
+
client that cached an earlier tool list. An answer to a call without the newer inputs keeps
|
|
39
|
+
the earlier shape.
|
|
40
|
+
|
|
41
|
+
Since 0.9.0 a skill can list `metadata.verified-runtimes`, a list drawn from `claude-code`,
|
|
42
|
+
`codex-cli`, `gemini-cli`, `grok-cli` and `antigravity`, meaning its effect was verified on
|
|
43
|
+
that runtime. `skill_find` and `skill_catalog` accept `runtime` and `verifiedOnly`; when either
|
|
44
|
+
is given, items carry `verifiedRuntimes` (omitted when empty). `runtime` never removes a skill: it marks
|
|
45
|
+
each item `verified` and lists verified ones first (within a package group in
|
|
46
|
+
`skill_catalog`). `verifiedOnly` drops the rest, keeping those verified on `runtime`, or on
|
|
47
|
+
any runtime when none is given. Without `runtime` the answer is ordered exactly as before.
|
|
48
|
+
A server can opt in with `rankByClientRuntime: true`: then, when `runtime` is not passed and
|
|
49
|
+
the MCP client's name is recognised (`claude-code`, `codex`, `gemini`, `grok`,
|
|
50
|
+
`antigravity`), that runtime is used for the ordering only, never for filtering.
|
|
51
|
+
`skill_find` then answers with `runtime`, the one the ordering used, or `null`.
|
|
52
|
+
|
|
53
|
+
`pmcp serve --prompts` also offers one prompt per skill, for hosts that turn prompts into
|
|
54
|
+
commands; the prompt's text is the skill body and its file list, with an optional `task`.
|
|
55
|
+
|
|
56
|
+
Marketplace plugins also carry commands, agents, hooks and MCP servers.
|
|
57
|
+
Commands are listed as skills. The others are listed under their own kind and
|
|
58
|
+
are left out of `skill_catalog` and `skill_find` unless `kind` asks for them
|
|
59
|
+
(`agent`, `hook`, `mcp`, or `any`); `skill_describe`, `skill_read` and
|
|
60
|
+
`skill_call` work on every kind.
|
|
61
|
+
|
|
62
|
+
## MCP Skills extension
|
|
63
|
+
|
|
64
|
+
The server also declares `io.modelcontextprotocol/skills` (SEP-2640): it
|
|
65
|
+
answers `skills/list` and `skills/get` (both with `ttlMs` and `cacheScope`), with
|
|
66
|
+
a sha256 digest and size per file. A skill qualifies when its frontmatter passes the
|
|
67
|
+
Agent Skills specification and its `name` matches its directory, and it stays within
|
|
68
|
+
512 files and 16 MiB; the rest remain reachable through the tools.
|
|
69
|
+
|
|
70
|
+
Every file of every skill the caller may see is a `skill://pmcp/<package>/<name>/<file>`
|
|
71
|
+
resource: `resources/list` lists each skill's `SKILL.md`, `resources/read` returns any file
|
|
72
|
+
(text, or a blob with its media type), and the template completes skill names and paths.
|
|
73
|
+
List-change notifications and subscriptions are not offered: they need a session, and the
|
|
74
|
+
HTTP handler is stateless.
|