@ebitex/content-mcp 0.4.95 → 0.5.98
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 +10 -3
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +7 -2
- package/dist/client.js.map +1 -1
- package/dist/resources/helpCorpus.generated.js +1 -1
- package/dist/resources/helpCorpus.generated.js.map +1 -1
- package/dist/server.d.ts +25 -2
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +52 -4
- package/dist/server.js.map +1 -1
- package/dist/tools/cursor.d.ts +55 -0
- package/dist/tools/cursor.d.ts.map +1 -0
- package/dist/tools/cursor.js +87 -0
- package/dist/tools/cursor.js.map +1 -0
- package/dist/tools/register.d.ts +11 -1
- package/dist/tools/register.d.ts.map +1 -1
- package/dist/tools/register.js +162 -11
- package/dist/tools/register.js.map +1 -1
- package/dist/tools/whoami.d.ts +31 -0
- package/dist/tools/whoami.d.ts.map +1 -0
- package/dist/tools/whoami.js +34 -0
- package/dist/tools/whoami.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -47,12 +47,13 @@ which role it acts as. Read it once; if it is not what you expected, stop.
|
|
|
47
47
|
|
|
48
48
|
## The tools
|
|
49
49
|
|
|
50
|
-
|
|
50
|
+
Ten, shaped around what an agent does rather than around REST routes.
|
|
51
51
|
|
|
52
52
|
| | |
|
|
53
53
|
|---|---|
|
|
54
|
+
| `content_whoami` | Where this key is scoped: organization, environment, role, scopes, this server's version, and which tools were withheld and why. Needs no scope, so a key that can do almost nothing can still ask why |
|
|
54
55
|
| `content_describe` | What can exist here: every field type with its **own settings schema**, plus this environment's Contracts and Templates |
|
|
55
|
-
| `content_find` | Locate entities by kind, search or external id |
|
|
56
|
+
| `content_find` | Locate entities by kind, search or external id, with one paging contract across both listings |
|
|
56
57
|
| `content_get` | Read one entity in full |
|
|
57
58
|
| `content_write` | Create or update one entity |
|
|
58
59
|
| `content_delete` | Delete one, behind an explicit confirmation |
|
|
@@ -62,7 +63,13 @@ Nine, shaped around what an agent does rather than around REST routes.
|
|
|
62
63
|
| `content_topology` | Where this environment sits: the delivery environments a publish lands in, and its promotion and inheritance neighbours. One hop only |
|
|
63
64
|
|
|
64
65
|
Which of them appear depends on your key's scopes: a read-scoped key gets a server with no write
|
|
65
|
-
tools at all, rather than tools that always fail.
|
|
66
|
+
tools at all, rather than tools that always fail. `content_whoami` is the exception and always
|
|
67
|
+
appears — it reports which tools were withheld and what each would need, so an absent tool is
|
|
68
|
+
explained rather than merely missing.
|
|
69
|
+
|
|
70
|
+
Every result also names the organization and environment it was answered in, and an empty one says so
|
|
71
|
+
explicitly. A key reads and writes exactly one authoring environment, so "no Contracts" always means
|
|
72
|
+
"none here" — an agent that reads it as "none anywhere" creates duplicates.
|
|
66
73
|
|
|
67
74
|
## Why it cannot drift
|
|
68
75
|
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;GAUG;AAEH,eAAO,MAAM,YAAY,2BAA2B,CAAA;AAEpD,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,CAAA;AAEpE,MAAM,MAAM,aAAa,GAAG;IAC1B,2EAA2E;IAC3E,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,OAAO,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;CAC5E,CAAA;AAED,MAAM,MAAM,aAAa,GAAG;IAC1B,OAAO,EAAE,MAAM,CAAA;IACf,GAAG,EAAE,MAAM,CAAA;IACX,4DAA4D;IAC5D,SAAS,CAAC,EAAE,OAAO,KAAK,CAAA;CACzB,CAAA;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,aAAa,GAAG,aAAa,
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;GAUG;AAEH,eAAO,MAAM,YAAY,2BAA2B,CAAA;AAEpD,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,CAAA;AAEpE,MAAM,MAAM,aAAa,GAAG;IAC1B,2EAA2E;IAC3E,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,OAAO,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;CAC5E,CAAA;AAED,MAAM,MAAM,aAAa,GAAG;IAC1B,OAAO,EAAE,MAAM,CAAA;IACf,GAAG,EAAE,MAAM,CAAA;IACX,4DAA4D;IAC5D,SAAS,CAAC,EAAE,OAAO,KAAK,CAAA;CACzB,CAAA;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,aAAa,GAAG,aAAa,CAqClE;AAED;;;;;;GAMG;AACH,wBAAgB,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,IAAI,CAAC,GAAG,MAAM,CASlG"}
|
package/dist/client.js
CHANGED
|
@@ -27,8 +27,13 @@ export function createClient(options) {
|
|
|
27
27
|
});
|
|
28
28
|
if (!response.ok)
|
|
29
29
|
throw await toContentApiError(response);
|
|
30
|
-
//
|
|
31
|
-
//
|
|
30
|
+
// 204 (every delete) carries no body. Returning `null` rather than throwing on an empty parse
|
|
31
|
+
// keeps the caller from having to know which responses are empty.
|
|
32
|
+
//
|
|
33
|
+
// A 202 is NOT empty — both publish phases, and since spec 775-management-import-async-job the
|
|
34
|
+
// import, answer `{ id, status }`. This comment used to say otherwise, harmlessly while nothing
|
|
35
|
+
// read a kick-off's body; it is corrected because something does now, and because a caller who
|
|
36
|
+
// believed it would return the envelope as though it were the operation's result.
|
|
32
37
|
if (response.status === 204)
|
|
33
38
|
return null;
|
|
34
39
|
const text = await response.text();
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAE/C;;;;;;;;;;GAUG;AAEH,MAAM,CAAC,MAAM,YAAY,GAAG,wBAAwB,CAAA;AAiBpD,MAAM,UAAU,YAAY,CAAC,OAAsB;IACjD,MAAM,OAAO,GAAG,OAAO,CAAC,SAAS,IAAI,UAAU,CAAC,KAAK,CAAA;IAErD,OAAO;QACL,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI;YAC9B,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,GAAG,YAAY,GAAG,IAAI,EAAE,EAAE;gBACzE,MAAM;gBACN,OAAO,EAAE;oBACP,aAAa,EAAE,UAAU,OAAO,CAAC,GAAG,EAAE;oBACtC,MAAM,EAAE,kBAAkB;oBAC1B,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC;iBACtE;gBACD,IAAI,EAAE,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;aAC5D,CAAC,CAAA;YAEF,IAAI,CAAC,QAAQ,CAAC,EAAE;gBAAE,MAAM,MAAM,iBAAiB,CAAC,QAAQ,CAAC,CAAA;YAEzD,
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAE/C;;;;;;;;;;GAUG;AAEH,MAAM,CAAC,MAAM,YAAY,GAAG,wBAAwB,CAAA;AAiBpD,MAAM,UAAU,YAAY,CAAC,OAAsB;IACjD,MAAM,OAAO,GAAG,OAAO,CAAC,SAAS,IAAI,UAAU,CAAC,KAAK,CAAA;IAErD,OAAO;QACL,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI;YAC9B,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,GAAG,YAAY,GAAG,IAAI,EAAE,EAAE;gBACzE,MAAM;gBACN,OAAO,EAAE;oBACP,aAAa,EAAE,UAAU,OAAO,CAAC,GAAG,EAAE;oBACtC,MAAM,EAAE,kBAAkB;oBAC1B,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC;iBACtE;gBACD,IAAI,EAAE,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;aAC5D,CAAC,CAAA;YAEF,IAAI,CAAC,QAAQ,CAAC,EAAE;gBAAE,MAAM,MAAM,iBAAiB,CAAC,QAAQ,CAAC,CAAA;YAEzD,8FAA8F;YAC9F,kEAAkE;YAClE,EAAE;YACF,+FAA+F;YAC/F,gGAAgG;YAChG,+FAA+F;YAC/F,kFAAkF;YAClF,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG;gBAAE,OAAO,IAAI,CAAA;YAExC,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAA;YAClC,IAAI,CAAC,IAAI;gBAAE,OAAO,IAAI,CAAA;YAEtB,IAAI,CAAC;gBACH,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;YACzB,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,IAAI,CAAA;YACb,CAAC;QACH,CAAC;KACF,CAAA;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,KAAK,CAAC,MAAoE;IACxF,MAAM,MAAM,GAAG,IAAI,eAAe,EAAE,CAAA;IACpC,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QACnD,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,EAAE;YAAE,SAAQ;QACnE,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAA;IACjC,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAA;IAClC,OAAO,QAAQ,CAAC,CAAC,CAAC,IAAI,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;AACvC,CAAC"}
|
|
@@ -6,7 +6,7 @@ export const HELP_TOPICS = [
|
|
|
6
6
|
{
|
|
7
7
|
"slug": "agent-authoring",
|
|
8
8
|
"title": "Building a content model through the API",
|
|
9
|
-
"body": "# Building a content model through the API\n\nThe rest of this help corpus describes Content as you drive it in Composer — tabs, panels, buttons.\nThe concepts all transfer; the steps do not. This page is the same model described in terms of the\nAPI, for a script or an agent working through the Content Management API rather than the interface.\n\nRead this first if you are about to create anything. Everything here is about *what the pieces are*;\nthe exact shape of each request is answered live by the API itself, and you should never guess it.\n\n## The one rule that saves the most time\n\n**Ask the server what things look like; do not assume.**\n\n`GET /field-types` returns every field type this platform has, each with its **own JSON Schema for\nits settings**. That schema is generated from the field type's own definition, so it is never out of\ndate — Composer's Contract builder renders its settings form from exactly this, rather than\nhard-coding a form per type. Use it the same way.\n\n`GET /contracts` and `GET /templates` tell you what this environment already has. Check before\ncreating: a duplicate is much harder to undo than it is to avoid.\n\nWhen a write is refused, the refusal names the failing field and says what is wrong with it. That\nmessage is the fastest route to a correct request. Read it and correct the one thing it names,\nrather than rewriting the payload.\n\n## The pieces, and what each one is for\n\nContent separates four concerns that many systems collapse into one. The separation is the reason\nthe same content can be rendered several ways, and reused in places its author never anticipated.\n\n### Contract — what content *is*\n\nA Contract is a type. It has a name, an external id, and a list of **fields**. Each field names a\nfield type (short text, rich text, number, date, blob, reference, component, presentation, category,\nlink, and so on) and carries that type's own settings.\n\nContracts support **inheritance**. A Contract may name a parent, and it then has the parent's fields\nplus its own. A Contract may be **abstract**, meaning nothing is ever an instance of it directly —\nit exists to be inherited from, and to be named where several concrete types should be accepted.\n\nContracts describe content and nothing about how it looks. No colours, no layout, no \"variant\".\n\n### Component — an instance of a Contract\n\nA Component is a piece of content: a Contract, plus a **document** holding a value for each field.\nIt has its own name and external id and lives in a folder.\n\nThe document's shape follows the Contract's fields exactly. What a field's value looks like depends\non its type *and* on its modifiers, below.\n\n### Template — how content is *rendered*\n\nA Template names which Contracts it can render, and has its own **settings Contract**: an ordinary\nContract describing the presentational choices that template offers — a variant, an alignment, how\nmany columns.\n\nThis is why Contracts stay free of presentation. \"A statement, centred, with a ghost button\" is one\nTemplate's settings over a plain statement Contract, not three fields on the Contract itself.\n\n### Presentation — a Template bound to content\n\nA **presentation value** is where the two meet: it names a Template, binds a Component (or holds an\ninline document), and carries settings and contextual values for this one use.\n\nA page is usually a Component whose fields hold presentation values — a hero, then some sections —\nand each of those points at content that may be used elsewhere, rendered differently.\n\n### Adapter — a reusable mapping between Contracts\n\nSometimes a Template needs a `card` and what you have is a `blog-page`. An Adapter is a named,\nreusable mapping from one Contract to another: one rule per output field, plus a small set of logic\nnodes for lists, conditions and type dispatch.\n\nAn Adapter is applied by the server — at preview, at publish, and at delivery — so the mapping is\ndefined once and behaves identically everywhere.\n\n### Experience — where content lives on the web\n\nThe Experience tree is the site's address space. A **site** is a root; **nodes** under it are pages,\neach with a slug. A node's path is its ancestors' slugs plus its own.\n\nA node's **payload** says what it renders — usually a presentation value, sometimes a redirect,\nsometimes nothing at all (a node with no payload is pure structure, giving its children a path\nsegment without being a page itself).\n\nCreating a node and setting its payload are **two separate calls**. That is not an oversight: a\nnode's identity and location change for different reasons than its content does.\n\n## The five modifiers\n\nAny field can carry any combination of these. They compose, and each one changes the shape of the\nvalue stored in the document — which is the part worth understanding before writing one.\n\n| Modifier | What it means | Effect on the value |\n|---|---|---|\n| Mandatory | A value is required | Validation refuses an empty one |\n| Enumerable | Many rather than one | The value becomes a list |\n| Localizable | Translatable per locale | The value becomes `{ default, translations }` |\n| Personalizable | Varies by audience | The value becomes `{ default, variants }` |\n| Contextual | Overridable per use | The value may be supplied where the Component is *used*, not only where it is defined |\n\nCardinality is Enumerable's job, never the field type's. There is no \"list of text\" field type;\nthere is a text field that is enumerable.\n\n**Contextual** is the one worth dwelling on, because it has no counterpart in most systems. A\ncontextual field's value can be set on the Component (a default) *and* overridden by whoever binds\nthat Component somewhere — a heading that reads one way on the home page and another on a listing,\nfrom one Component with one document. Those overrides are the `contextualValues` that travel with a\nreference or a presentation value.\n\n## An order of operations that works\n\nDependencies run one way, so build in this order and nothing is ever waiting on something that does\nnot exist yet.\n\n1. **Describe.** `GET /field-types`, `/contracts`, `/templates`. Learn what exists before adding to\n it.\n2. **Contracts.** Parents before children, since a child names its parent.\n3. **Templates.** After the Contracts they render, since a Template names them.\n4. **Components.** After their Contract, and after any Contract they reference.\n5. **A site**, if the environment has none. Then **nodes** under it, parents before children.\n6. **Node payloads.** After both the node and the Component it binds.\n7. **Publish.** Plan first, read the blockers, then publish.\n\nTwo ordering facts that are easy to get wrong: a Component referencing another Component needs that\none to exist first, and publishing follows the dependency closure automatically — so publishing a\npage will normally publish the content it binds, and the plan is where you see exactly what that\nmeans before it happens.\n\n## Publishing\n\nPublishing is two calls, and collapsing them would hide the thing that matters.\n\n**Plan** resolves the full dependency closure of what you asked to publish and reports every\n**blocker** — an unresolvable reference, a workflow state that forbids publishing, a document that\nfails validation. **Execute** publishes what the plan named.\n\nBoth are jobs: each returns an operation id, and you poll it. A real closure is too large to finish\ninside an HTTP request, which is why.\n\nRead the plan. It is the only place the system tells you what is about to change beyond what you\nexplicitly named.\n\n## Where writes land\n\nA management key is bound to exactly one organization and one **authoring environment**, and it acts\nas one **role**. It cannot reach another environment, and it is subject to the same branch access\nrules and workflow gating a person with that role is.\n\nThat binding is the real safety boundary, so it is worth confirming rather than assuming: ask the\nAPI who the key is before writing anything. If the answer is not the environment you expected, stop\n— nothing else about the request will tell you.\n\nThen ask where the environment sits (`GET /topology`, or the `content_topology` tool). It names this\nenvironment's direct neighbours, and each one tells you something about your own work:\n\n- **Publishes to.** Where a publish from here lands. If one of these is a live website, a publish\n changes that website. With two or more, a publish has to say which one.\n- **Inherits from.** Content synced from this parent is read-only here. A refusal saying content is\n inherited means the change has to be made in the parent instead.\n- **Inherited by.** These environments receive this one's library the next time they sync, so a\n change here spreads there.\n- **Promoted from.** Someone promoting from one of these can overwrite what you write here.\n- **Promotes to.** Where this content goes when someone promotes it. You cannot promote yourself.\n\nNothing in the answer says which environment is production. Judge that from the names, and ask the\nperson you are working for when it is not obvious.\n\n## Things that commonly go wrong\n\n- **Guessing a field type's settings** instead of reading its schema. Every field type declares its\n own; there is nothing to guess.\n- **Creating a duplicate** because an external id was not checked first. External ids are how a\n model refers to itself across environments; a duplicate is a lasting problem.\n- **Putting presentation on a Contract.** If you are adding a field called `variant`, `align`,\n `theme` or `columns` to a Contract, it almost certainly belongs in a Template's settings.\n- **Forgetting a node's payload.** A node created and never given one is a real, published,\n completely blank page.\n- **Treating a publish plan as a formality.** It is where blockers appear, and they do not appear\n anywhere else until something is already wrong.\n\n## Related\n\n- [Contracts](contracts.md) — the type system in depth\n- [Templates](templates.md) — presentation\n- [Components](components.md) — authoring content\n- [Content Adapters](content-adapters.md) — mappings\n- [Composer](content-composer.md) — the Experience tree\n- [Publishing](publishing.md) — the publish pipeline\n- [Management keys](management-keys.md) — minting and scoping a key\n"
|
|
9
|
+
"body": "# Building a content model through the API\n\nThe rest of this help corpus describes Content as you drive it in Composer — tabs, panels, buttons.\nThe concepts all transfer; the steps do not. This page is the same model described in terms of the\nAPI, for a script or an agent working through the Content Management API rather than the interface.\n\nRead this first if you are about to create anything. Everything here is about *what the pieces are*;\nthe exact shape of each request is answered live by the API itself, and you should never guess it.\n\n## The one rule that saves the most time\n\n**Ask the server what things look like; do not assume.**\n\n`GET /field-types` returns every field type this platform has, each with its **own JSON Schema for\nits settings**. That schema is generated from the field type's own definition, so it is never out of\ndate — Composer's Contract builder renders its settings form from exactly this, rather than\nhard-coding a form per type. Use it the same way.\n\n`GET /contracts` and `GET /templates` tell you what this environment already has. Check before\ncreating: a duplicate is much harder to undo than it is to avoid.\n\nWhen a write is refused, the refusal names the failing field and says what is wrong with it. That\nmessage is the fastest route to a correct request. Read it and correct the one thing it names,\nrather than rewriting the payload.\n\n## The pieces, and what each one is for\n\nContent separates four concerns that many systems collapse into one. The separation is the reason\nthe same content can be rendered several ways, and reused in places its author never anticipated.\n\n### Contract — what content *is*\n\nA Contract is a type. It has a name, an external id, and a list of **fields**. Each field names a\nfield type (short text, rich text, number, date, blob, reference, component, presentation, category,\nlink, and so on) and carries that type's own settings.\n\nContracts support **inheritance**. A Contract may name a parent, and it then has the parent's fields\nplus its own. A Contract may be **abstract**, meaning nothing is ever an instance of it directly —\nit exists to be inherited from, and to be named where several concrete types should be accepted.\n\nContracts describe content and nothing about how it looks. No colours, no layout, no \"variant\".\n\n### Component — an instance of a Contract\n\nA Component is a piece of content: a Contract, plus a **document** holding a value for each field.\nIt has its own name and external id and lives in a folder.\n\nThe document's shape follows the Contract's fields exactly. What a field's value looks like depends\non its type *and* on its modifiers, below.\n\n### Template — how content is *rendered*\n\nA Template names which Contracts it can render, and has its own **settings Contract**: an ordinary\nContract describing the presentational choices that template offers — a variant, an alignment, how\nmany columns.\n\nThis is why Contracts stay free of presentation. \"A statement, centred, with a ghost button\" is one\nTemplate's settings over a plain statement Contract, not three fields on the Contract itself.\n\n### Presentation — a Template bound to content\n\nA **presentation value** is where the two meet: it names a Template, binds a Component (or holds an\ninline document), and carries settings and contextual values for this one use.\n\nA page is usually a Component whose fields hold presentation values — a hero, then some sections —\nand each of those points at content that may be used elsewhere, rendered differently.\n\n### Adapter — a reusable mapping between Contracts\n\nSometimes a Template needs a `card` and what you have is a `blog-page`. An Adapter is a named,\nreusable mapping from one Contract to another: one rule per output field, plus a small set of logic\nnodes for lists, conditions and type dispatch.\n\nAn Adapter is applied by the server — at preview, at publish, and at delivery — so the mapping is\ndefined once and behaves identically everywhere.\n\n### Experience — where content lives on the web\n\nThe Experience tree is the site's address space. A **site** is a root; **nodes** under it are pages,\neach with a slug. A node's path is its ancestors' slugs plus its own.\n\nA node's **payload** says what it renders — usually a presentation value, sometimes a redirect,\nsometimes nothing at all (a node with no payload is pure structure, giving its children a path\nsegment without being a page itself).\n\nCreating a node and setting its payload are **two separate calls**. That is not an oversight: a\nnode's identity and location change for different reasons than its content does.\n\n## The five modifiers\n\nAny field can carry any combination of these. They compose, and each one changes the shape of the\nvalue stored in the document — which is the part worth understanding before writing one.\n\n| Modifier | What it means | Effect on the value |\n|---|---|---|\n| Mandatory | A value is required | Validation refuses an empty one |\n| Enumerable | Many rather than one | The value becomes a list |\n| Localizable | Translatable per locale | The value becomes `{ default, translations }` |\n| Personalizable | Varies by audience | The value becomes `{ default, variants }` |\n| Contextual | Overridable per use | The value may be supplied where the Component is *used*, not only where it is defined |\n\nCardinality is Enumerable's job, never the field type's. There is no \"list of text\" field type;\nthere is a text field that is enumerable.\n\n**Contextual** is the one worth dwelling on, because it has no counterpart in most systems. A\ncontextual field's value can be set on the Component (a default) *and* overridden by whoever binds\nthat Component somewhere — a heading that reads one way on the home page and another on a listing,\nfrom one Component with one document. Those overrides are the `contextualValues` that travel with a\nreference or a presentation value.\n\n## An order of operations that works\n\nDependencies run one way, so build in this order and nothing is ever waiting on something that does\nnot exist yet.\n\n1. **Describe.** `GET /field-types`, `/contracts`, `/templates`. Learn what exists before adding to\n it.\n2. **Contracts.** Parents before children, since a child names its parent.\n3. **Templates.** After the Contracts they render, since a Template names them.\n4. **Components.** After their Contract, and after any Contract they reference.\n5. **A site**, if the environment has none. Then **nodes** under it, parents before children.\n6. **Node payloads.** After both the node and the Component it binds.\n7. **Publish.** Plan first, read the blockers, then publish.\n\nTwo ordering facts that are easy to get wrong: a Component referencing another Component needs that\none to exist first, and publishing follows the dependency closure automatically — so publishing a\npage will normally publish the content it binds, and the plan is where you see exactly what that\nmeans before it happens.\n\n## Publishing\n\nPublishing is two calls, and collapsing them would hide the thing that matters.\n\n**Plan** resolves the full dependency closure of what you asked to publish and reports every\n**blocker** — an unresolvable reference, a workflow state that forbids publishing, a document that\nfails validation. **Execute** publishes what the plan named.\n\nBoth are jobs: each returns an operation id, and you poll it. A real closure is too large to finish\ninside an HTTP request, which is why.\n\nRead the plan. It is the only place the system tells you what is about to change beyond what you\nexplicitly named.\n\n## Where writes land\n\nA management key is bound to exactly one organization and one **authoring environment**, and it acts\nas one **role**. It cannot reach another environment, and it is subject to the same branch access\nrules and workflow gating a person with that role is.\n\nThat binding is the real safety boundary, so it is worth confirming rather than assuming: ask the\nAPI who the key is before writing anything. If the answer is not the environment you expected, stop\n— nothing else about the request will tell you.\n\nThen ask where the environment sits (`GET /topology`, or the `content_topology` tool). It names this\nenvironment's direct neighbours, and each one tells you something about your own work:\n\n- **Publishes to.** Where a publish from here lands. If one of these is a live website, a publish\n changes that website. With two or more, a publish has to say which one.\n- **Inherits from.** Content synced from this parent is read-only here. A refusal saying content is\n inherited means the change has to be made in the parent instead.\n- **Inherited by.** These environments receive this one's library the next time they sync, so a\n change here spreads there.\n- **Promoted from.** Someone promoting from one of these can overwrite what you write here.\n- **Promotes to.** Where this content goes when someone promotes it. You cannot promote yourself.\n\nNothing in the answer says which environment is production. Judge that from the names, and ask the\nperson you are working for when it is not obvious.\n\n## What an empty answer means\n\nThe binding governs **reads** exactly as it governs writes, and that changes how an empty result\nshould be read. `GET /contracts` returning nothing means *this environment has no Contracts*. It does\nnot mean the organization has none, and it certainly does not mean the account has no content.\n\nThe difference matters because acting on the wrong reading is expensive in one direction: concluding\n\"nothing exists\" and creating a model that already exists elsewhere produces duplicates, which are\nmuch harder to undo than to avoid. The safe habit is to confirm the scope before concluding anything\nfrom an empty list — `GET /whoami`, or the `content_whoami` tool, which needs no permissions at all\nprecisely so that a key holding almost nothing can still ask.\n\nA `404` on a single-entity read is the same fact in another shape: not found *here*. The entity may\nexist in another environment, and this key cannot see it.\n\n## Things that commonly go wrong\n\n- **Guessing a field type's settings** instead of reading its schema. Every field type declares its\n own; there is nothing to guess.\n- **Creating a duplicate** because an external id was not checked first. External ids are how a\n model refers to itself across environments; a duplicate is a lasting problem.\n- **Putting presentation on a Contract.** If you are adding a field called `variant`, `align`,\n `theme` or `columns` to a Contract, it almost certainly belongs in a Template's settings.\n- **Forgetting a node's payload.** A node created and never given one is a real, published,\n completely blank page.\n- **Treating a publish plan as a formality.** It is where blockers appear, and they do not appear\n anywhere else until something is already wrong.\n\n## Related\n\n- [Contracts](contracts.md) — the type system in depth\n- [Templates](templates.md) — presentation\n- [Components](components.md) — authoring content\n- [Content Adapters](content-adapters.md) — mappings\n- [Composer](content-composer.md) — the Experience tree\n- [Publishing](publishing.md) — the publish pipeline\n- [Management keys](management-keys.md) — minting and scoping a key\n"
|
|
10
10
|
},
|
|
11
11
|
{
|
|
12
12
|
"slug": "blog-series",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpCorpus.generated.js","sourceRoot":"","sources":["../../src/resources/helpCorpus.generated.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,EAAE;AACF,kGAAkG;AAClG,oGAAoG;AAIpG,MAAM,CAAC,MAAM,WAAW,GAAgB;IACtC;QACE,MAAM,EAAE,iBAAiB;QACzB,OAAO,EAAE,0CAA0C;QACnD,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"helpCorpus.generated.js","sourceRoot":"","sources":["../../src/resources/helpCorpus.generated.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,EAAE;AACF,kGAAkG;AAClG,oGAAoG;AAIpG,MAAM,CAAC,MAAM,WAAW,GAAgB;IACtC;QACE,MAAM,EAAE,iBAAiB;QACzB,OAAO,EAAE,0CAA0C;QACnD,MAAM,EAAE,knWAAknW;KAC3nW;IACD;QACE,MAAM,EAAE,aAAa;QACrB,OAAO,EAAE,aAAa;QACtB,MAAM,EAAE,wnGAAwnG;KACjoG;IACD;QACE,MAAM,EAAE,YAAY;QACpB,OAAO,EAAE,sBAAsB;QAC/B,MAAM,EAAE,igVAAigV;KAC1gV;IACD;QACE,MAAM,EAAE,kBAAkB;QAC1B,OAAO,EAAE,kCAAkC;QAC3C,MAAM,EAAE,6okBAA6okB;KACtpkB;IACD;QACE,MAAM,EAAE,mBAAmB;QAC3B,OAAO,EAAE,0BAA0B;QACnC,MAAM,EAAE,6oLAA6oL;KACtpL;IACD;QACE,MAAM,EAAE,kBAAkB;QAC1B,OAAO,EAAE,gCAAgC;QACzC,MAAM,EAAE,sxeAAsxe;KAC/xe;IACD;QACE,MAAM,EAAE,sBAAsB;QAC9B,OAAO,EAAE,sBAAsB;QAC/B,MAAM,EAAE,m8hBAAm8hB;KAC58hB;IACD;QACE,MAAM,EAAE,eAAe;QACvB,OAAO,EAAE,qCAAqC;QAC9C,MAAM,EAAE,q3FAAq3F;KAC93F;IACD;QACE,MAAM,EAAE,yBAAyB;QACjC,OAAO,EAAE,4BAA4B;QACrC,MAAM,EAAE,2jRAA2jR;KACpkR;IACD;QACE,MAAM,EAAE,mBAAmB;QAC3B,OAAO,EAAE,mBAAmB;QAC5B,MAAM,EAAE,6/HAA6/H;KACtgI;IACD;QACE,MAAM,EAAE,iBAAiB;QACzB,OAAO,EAAE,4CAA4C;QACrD,MAAM,EAAE,22GAA22G;KACp3G;IACD;QACE,MAAM,EAAE,kBAAkB;QAC1B,OAAO,EAAE,UAAU;QACnB,MAAM,EAAE,wvJAAwvJ;KACjwJ;IACD;QACE,MAAM,EAAE,kBAAkB;QAC1B,OAAO,EAAE,oBAAoB;QAC7B,MAAM,EAAE,4mPAA4mP;KACrnP;IACD;QACE,MAAM,EAAE,WAAW;QACnB,OAAO,EAAE,iCAAiC;QAC1C,MAAM,EAAE,s2XAAs2X;KAC/2X;IACD;QACE,MAAM,EAAE,qBAAqB;QAC7B,OAAO,EAAE,qBAAqB;QAC9B,MAAM,EAAE,+iFAA+iF;KACxjF;IACD;QACE,MAAM,EAAE,eAAe;QACvB,OAAO,EAAE,mBAAmB;QAC5B,MAAM,EAAE,6+HAA6+H;KACt/H;IACD;QACE,MAAM,EAAE,mBAAmB;QAC3B,OAAO,EAAE,mBAAmB;QAC5B,MAAM,EAAE,upIAAupI;KAChqI;IACD;QACE,MAAM,EAAE,iBAAiB;QACzB,OAAO,EAAE,iBAAiB;QAC1B,MAAM,EAAE,2rLAA2rL;KACpsL;IACD;QACE,MAAM,EAAE,YAAY;QACpB,OAAO,EAAE,oBAAoB;QAC7B,MAAM,EAAE,2hVAA2hV;KACpiV;IACD;QACE,MAAM,EAAE,mBAAmB;QAC3B,OAAO,EAAE,+BAA+B;QACxC,MAAM,EAAE,g2EAAg2E;KACz2E;IACD;QACE,MAAM,EAAE,WAAW;QACnB,OAAO,EAAE,mCAAmC;QAC5C,MAAM,EAAE,8vKAA8vK;KACvwK;IACD;QACE,MAAM,EAAE,kBAAkB;QAC1B,OAAO,EAAE,kBAAkB;QAC3B,MAAM,EAAE,itIAAitI;KAC1tI;CACF,CAAA"}
|
package/dist/server.d.ts
CHANGED
|
@@ -6,8 +6,31 @@ import { type Session } from './session.js';
|
|
|
6
6
|
* (`session.has`), and which routes exist is decided by `routes.ts`. This file only wires them.
|
|
7
7
|
*/
|
|
8
8
|
export declare const SERVER_NAME = "ebitex-content";
|
|
9
|
-
/**
|
|
10
|
-
|
|
9
|
+
/**
|
|
10
|
+
* What this build reports in the MCP handshake, and in the startup banner.
|
|
11
|
+
*
|
|
12
|
+
* **Read from the installed `package.json` at load, never written here** (spec
|
|
13
|
+
* 791-content-mcp-version-reporting). It used to be the literal `'0.1.0'`, under a comment claiming
|
|
14
|
+
* the build kept it in step with `package.json`. The build does no such thing: `publish-packages.yml`
|
|
15
|
+
* stamps the version with `npm version` and never touches source, so *every published build announced
|
|
16
|
+
* `0.1.0`* — and that number is exactly what a reporter needs when two agent processes disagree about
|
|
17
|
+
* which tools exist, which is the situation it was useless in. `content_topology` is the newest tool,
|
|
18
|
+
* so a stale build has the other eight and not it; scopes cannot produce that, since the five read
|
|
19
|
+
* tools share one registration block.
|
|
20
|
+
*
|
|
21
|
+
* **Why not a generated constant**, following `scripts/bundleHelp.mjs`, which is the obvious shape:
|
|
22
|
+
* the publish workflow runs `npm version` *after* `npm run build`, so a prebuild stamp would bake the
|
|
23
|
+
* committed `0.0.0-dev` placeholder into every release — the same symptom with a different wrong
|
|
24
|
+
* number. Reading at runtime is immune to that ordering, because it reads the file `npm version`
|
|
25
|
+
* actually wrote. Reordering the workflow would work too, and is worse: it is deliberately
|
|
26
|
+
* package-agnostic and shared by four packages, so a change made to suit this one has three other
|
|
27
|
+
* consumers and no test.
|
|
28
|
+
*
|
|
29
|
+
* `../package.json` resolves correctly from both places this module ever runs — `dist/server.js` in a
|
|
30
|
+
* published install, and `src/server.ts` under vitest — which is why the path needs no build
|
|
31
|
+
* configuration and no conditional.
|
|
32
|
+
*/
|
|
33
|
+
export declare const SERVER_VERSION: string;
|
|
11
34
|
export type BuiltServer = {
|
|
12
35
|
server: McpServer;
|
|
13
36
|
session: Session;
|
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AAEnE,OAAO,EAAc,KAAK,YAAY,EAAE,MAAM,aAAa,CAAA;AAE3D,OAAO,EAAmC,KAAK,OAAO,EAAE,MAAM,cAAc,CAAA;AAG5E;;;GAGG;AAEH,eAAO,MAAM,WAAW,mBAAmB,CAAA;AAE3C;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,cAAc,EAAE,MAAsB,CAAA;AAiBnD,MAAM,MAAM,WAAW,GAAG;IACxB,MAAM,EAAE,SAAS,CAAA;IACjB,OAAO,EAAE,OAAO,CAAA;IAChB,6EAA6E;IAC7E,MAAM,EAAE,MAAM,CAAA;CACf,CAAA;AAED,wBAAsB,WAAW,CAAC,OAAO,CAAC,EAAE;IAC1C,MAAM,CAAC,EAAE,YAAY,CAAA;IACrB,SAAS,CAAC,EAAE,OAAO,KAAK,CAAA;CACzB,GAAG,OAAO,CAAC,WAAW,CAAC,CAkCvB;AAED;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM,CAuB5E"}
|
package/dist/server.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { createRequire } from 'node:module';
|
|
1
2
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
3
|
import { createClient } from './client.js';
|
|
3
4
|
import { readConfig } from './config.js';
|
|
@@ -9,8 +10,46 @@ import { registerTools } from './tools/register.js';
|
|
|
9
10
|
* (`session.has`), and which routes exist is decided by `routes.ts`. This file only wires them.
|
|
10
11
|
*/
|
|
11
12
|
export const SERVER_NAME = 'ebitex-content';
|
|
12
|
-
/**
|
|
13
|
-
|
|
13
|
+
/**
|
|
14
|
+
* What this build reports in the MCP handshake, and in the startup banner.
|
|
15
|
+
*
|
|
16
|
+
* **Read from the installed `package.json` at load, never written here** (spec
|
|
17
|
+
* 791-content-mcp-version-reporting). It used to be the literal `'0.1.0'`, under a comment claiming
|
|
18
|
+
* the build kept it in step with `package.json`. The build does no such thing: `publish-packages.yml`
|
|
19
|
+
* stamps the version with `npm version` and never touches source, so *every published build announced
|
|
20
|
+
* `0.1.0`* — and that number is exactly what a reporter needs when two agent processes disagree about
|
|
21
|
+
* which tools exist, which is the situation it was useless in. `content_topology` is the newest tool,
|
|
22
|
+
* so a stale build has the other eight and not it; scopes cannot produce that, since the five read
|
|
23
|
+
* tools share one registration block.
|
|
24
|
+
*
|
|
25
|
+
* **Why not a generated constant**, following `scripts/bundleHelp.mjs`, which is the obvious shape:
|
|
26
|
+
* the publish workflow runs `npm version` *after* `npm run build`, so a prebuild stamp would bake the
|
|
27
|
+
* committed `0.0.0-dev` placeholder into every release — the same symptom with a different wrong
|
|
28
|
+
* number. Reading at runtime is immune to that ordering, because it reads the file `npm version`
|
|
29
|
+
* actually wrote. Reordering the workflow would work too, and is worse: it is deliberately
|
|
30
|
+
* package-agnostic and shared by four packages, so a change made to suit this one has three other
|
|
31
|
+
* consumers and no test.
|
|
32
|
+
*
|
|
33
|
+
* `../package.json` resolves correctly from both places this module ever runs — `dist/server.js` in a
|
|
34
|
+
* published install, and `src/server.ts` under vitest — which is why the path needs no build
|
|
35
|
+
* configuration and no conditional.
|
|
36
|
+
*/
|
|
37
|
+
export const SERVER_VERSION = readVersion();
|
|
38
|
+
/**
|
|
39
|
+
* Deliberately `0.0.0-unknown` rather than `0.0.0` on failure: a plausible-looking version is
|
|
40
|
+
* indistinguishable from a real one, which is the defect this whole mechanism exists to remove. And
|
|
41
|
+
* deliberately not a throw — a version is diagnostic, never load-bearing, so refusing to start
|
|
42
|
+
* because a diagnostic is missing would trade a small confusion for a total outage.
|
|
43
|
+
*/
|
|
44
|
+
function readVersion() {
|
|
45
|
+
try {
|
|
46
|
+
const pkg = createRequire(import.meta.url)('../package.json');
|
|
47
|
+
return typeof pkg.version === 'string' && pkg.version.length > 0 ? pkg.version : '0.0.0-unknown';
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
return '0.0.0-unknown';
|
|
51
|
+
}
|
|
52
|
+
}
|
|
14
53
|
export async function buildServer(options) {
|
|
15
54
|
const config = options?.config ?? readConfig();
|
|
16
55
|
const client = createClient({ baseUrl: config.baseUrl, key: config.key, fetchImpl: options?.fetchImpl });
|
|
@@ -25,9 +64,15 @@ export async function buildServer(options) {
|
|
|
25
64
|
'ebitex-content://help/agent-authoring resource before building a model; it explains what ' +
|
|
26
65
|
'Contracts, Templates, Presentations, Adapters and the Experience tree are for, and the ' +
|
|
27
66
|
'order to create them in. When a write is refused, the refusal names the failing field: ' +
|
|
28
|
-
'correct that one thing and call again.'
|
|
67
|
+
'correct that one thing and call again. ' +
|
|
68
|
+
// Spec #792, and it belongs here rather than only in a tool description because an agent
|
|
69
|
+
// reads instructions before its first call — which is before the first empty result it
|
|
70
|
+
// would otherwise misread as "nothing exists".
|
|
71
|
+
'This key is bound to exactly one organization and one authoring environment, so every ' +
|
|
72
|
+
'result is scoped to that environment: an empty list means nothing matched there, not that ' +
|
|
73
|
+
'nothing exists. content_whoami reports the binding, and needs no scope.',
|
|
29
74
|
});
|
|
30
|
-
registerTools(server, { client, session, target });
|
|
75
|
+
registerTools(server, { client, session, target, serverVersion: SERVER_VERSION });
|
|
31
76
|
registerResources(server, { client, session });
|
|
32
77
|
return { server, session, banner: startupBanner(config, session) };
|
|
33
78
|
}
|
|
@@ -45,6 +90,9 @@ export function startupBanner(config, session) {
|
|
|
45
90
|
const { who } = session;
|
|
46
91
|
const lines = [
|
|
47
92
|
'ebitex Content MCP',
|
|
93
|
+
// First, above the binding: when two agent processes disagree about which tools exist, this is
|
|
94
|
+
// the first thing to compare, and the operator reading stderr is who files that report.
|
|
95
|
+
` version ${SERVER_VERSION}`,
|
|
48
96
|
` api ${config.baseUrl}`,
|
|
49
97
|
` organization ${who.organizationName ?? who.organizationId}`,
|
|
50
98
|
` environment ${who.environmentName ?? who.environmentId}`,
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AACnE,OAAO,EAAE,YAAY,EAAsB,MAAM,aAAa,CAAA;AAC9D,OAAO,EAAE,UAAU,EAAqB,MAAM,aAAa,CAAA;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AAC3D,OAAO,EAAE,cAAc,EAAE,eAAe,EAAgB,MAAM,cAAc,CAAA;AAC5E,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAEnD;;;GAGG;AAEH,MAAM,CAAC,MAAM,WAAW,GAAG,gBAAgB,CAAA;AAE3C
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `content_find`'s paging cursor.
|
|
3
|
+
*
|
|
4
|
+
* **The problem this exists for.** `content_find` puts two listings behind one tool, because both
|
|
5
|
+
* answer "what is already here" and an agent asking that should not have to know which one can
|
|
6
|
+
* filter. But they page differently, and not merely by parameter name: `GET /items` is cursor-paged
|
|
7
|
+
* (`{items, nextCursor}`), while `GET /components` is offset-paged (`page`/`pageSize`, answering
|
|
8
|
+
* `{items, total, page, pageSize}`) and returns no cursor at all. The tool's own schema promises
|
|
9
|
+
* `limit` and `cursor` for both, and the search branch once forwarded neither — so an agent
|
|
10
|
+
* paginating a search got page one forever, with nothing indicating its parameters were discarded.
|
|
11
|
+
*
|
|
12
|
+
* So the tool keeps its promise and normalizes: this module turns a page number into an opaque
|
|
13
|
+
* cursor, and an agent never sees which paging model it is riding.
|
|
14
|
+
*
|
|
15
|
+
* **This is not the knowledge the drift guard forbids.** Knowing that `/components` pages by `page`
|
|
16
|
+
* is the same category as knowing a Contract lives at `/contracts` — a fact about one endpoint's
|
|
17
|
+
* request shape, not about what a Contract may contain. It follows `toPublishItem`'s precedent: this
|
|
18
|
+
* server already normalizes an endpoint's irregular shape rather than documenting it, precisely
|
|
19
|
+
* because neither obvious move worked unaided.
|
|
20
|
+
*/
|
|
21
|
+
/** What a cursor turned out to be. `malformed` is separate from `passthrough` on purpose — see {@link decodeCursor}. */
|
|
22
|
+
export type DecodedCursor = {
|
|
23
|
+
kind: 'search';
|
|
24
|
+
page: number;
|
|
25
|
+
} | {
|
|
26
|
+
kind: 'passthrough';
|
|
27
|
+
} | {
|
|
28
|
+
kind: 'malformed';
|
|
29
|
+
};
|
|
30
|
+
/** The next page of a components search, as one opaque string. */
|
|
31
|
+
export declare function encodeSearchCursor(page: number): string;
|
|
32
|
+
/**
|
|
33
|
+
* Classifies a cursor the agent sent back.
|
|
34
|
+
*
|
|
35
|
+
* A string without the prefix is the server's own and passes through to `/items` untouched — which
|
|
36
|
+
* is exactly what it already was before this spec, so nothing an agent is holding mid-session breaks.
|
|
37
|
+
*
|
|
38
|
+
* A string *with* the prefix that will not decode is `malformed` rather than quietly becoming page
|
|
39
|
+
* one. Defaulting it would be this spec's own defect in miniature: an input accepted, discarded, and
|
|
40
|
+
* answered with a plausible-looking result.
|
|
41
|
+
*/
|
|
42
|
+
export declare function decodeCursor(cursor: string | undefined): DecodedCursor;
|
|
43
|
+
/**
|
|
44
|
+
* The cursor for the page after this one, or `null` when there is none.
|
|
45
|
+
*
|
|
46
|
+
* **`null` has to mean exactly "no next page", never "probably not".** An agent paging until
|
|
47
|
+
* `nextCursor` is `null` must terminate, and must not make one extra call that returns an empty
|
|
48
|
+
* page. Derived from the response's own `total`/`page`/`pageSize` rather than from what was
|
|
49
|
+
* requested, since the server may legitimately return a smaller page than asked for.
|
|
50
|
+
*
|
|
51
|
+
* Returns `null` for any response whose paging members are missing or unusable: an unpageable answer
|
|
52
|
+
* is the end of the walk, which terminates, where an emitted cursor would loop.
|
|
53
|
+
*/
|
|
54
|
+
export declare function nextSearchCursor(response: unknown): string | null;
|
|
55
|
+
//# sourceMappingURL=cursor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cursor.d.ts","sourceRoot":"","sources":["../../src/tools/cursor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAeH,wHAAwH;AACxH,MAAM,MAAM,aAAa,GACrB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAChC;IAAE,IAAI,EAAE,aAAa,CAAA;CAAE,GACvB;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE,CAAA;AAEzB,kEAAkE;AAClE,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,aAAa,CAmBtE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CASjE"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `content_find`'s paging cursor.
|
|
3
|
+
*
|
|
4
|
+
* **The problem this exists for.** `content_find` puts two listings behind one tool, because both
|
|
5
|
+
* answer "what is already here" and an agent asking that should not have to know which one can
|
|
6
|
+
* filter. But they page differently, and not merely by parameter name: `GET /items` is cursor-paged
|
|
7
|
+
* (`{items, nextCursor}`), while `GET /components` is offset-paged (`page`/`pageSize`, answering
|
|
8
|
+
* `{items, total, page, pageSize}`) and returns no cursor at all. The tool's own schema promises
|
|
9
|
+
* `limit` and `cursor` for both, and the search branch once forwarded neither — so an agent
|
|
10
|
+
* paginating a search got page one forever, with nothing indicating its parameters were discarded.
|
|
11
|
+
*
|
|
12
|
+
* So the tool keeps its promise and normalizes: this module turns a page number into an opaque
|
|
13
|
+
* cursor, and an agent never sees which paging model it is riding.
|
|
14
|
+
*
|
|
15
|
+
* **This is not the knowledge the drift guard forbids.** Knowing that `/components` pages by `page`
|
|
16
|
+
* is the same category as knowing a Contract lives at `/contracts` — a fact about one endpoint's
|
|
17
|
+
* request shape, not about what a Contract may contain. It follows `toPublishItem`'s precedent: this
|
|
18
|
+
* server already normalizes an endpoint's irregular shape rather than documenting it, precisely
|
|
19
|
+
* because neither obvious move worked unaided.
|
|
20
|
+
*/
|
|
21
|
+
/**
|
|
22
|
+
* The literal marker every cursor this module issues carries.
|
|
23
|
+
*
|
|
24
|
+
* **Detection has to be exact, not probabilistic.** An `/items` cursor is itself opaque base64url
|
|
25
|
+
* (the server's own `ManagementItemsCursor`), so "try to parse it as ours" would be a guess that
|
|
26
|
+
* usually works — and a call that usually works is the entire subject of this spec. With the prefix,
|
|
27
|
+
* a cursor either is ours or is not, with no third answer.
|
|
28
|
+
*
|
|
29
|
+
* The `1` is a format version. A later change to what we encode is then detectable rather than
|
|
30
|
+
* silently misread as the current shape.
|
|
31
|
+
*/
|
|
32
|
+
const PREFIX = 'mcpc1.';
|
|
33
|
+
/** The next page of a components search, as one opaque string. */
|
|
34
|
+
export function encodeSearchCursor(page) {
|
|
35
|
+
return PREFIX + Buffer.from(JSON.stringify({ b: 'components', p: page }), 'utf8').toString('base64url');
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Classifies a cursor the agent sent back.
|
|
39
|
+
*
|
|
40
|
+
* A string without the prefix is the server's own and passes through to `/items` untouched — which
|
|
41
|
+
* is exactly what it already was before this spec, so nothing an agent is holding mid-session breaks.
|
|
42
|
+
*
|
|
43
|
+
* A string *with* the prefix that will not decode is `malformed` rather than quietly becoming page
|
|
44
|
+
* one. Defaulting it would be this spec's own defect in miniature: an input accepted, discarded, and
|
|
45
|
+
* answered with a plausible-looking result.
|
|
46
|
+
*/
|
|
47
|
+
export function decodeCursor(cursor) {
|
|
48
|
+
if (cursor === undefined || !cursor.startsWith(PREFIX))
|
|
49
|
+
return { kind: 'passthrough' };
|
|
50
|
+
try {
|
|
51
|
+
const decoded = JSON.parse(Buffer.from(cursor.slice(PREFIX.length), 'base64url').toString('utf8'));
|
|
52
|
+
if (typeof decoded === 'object' &&
|
|
53
|
+
decoded !== null &&
|
|
54
|
+
decoded.b === 'components' &&
|
|
55
|
+
Number.isInteger(decoded.p) &&
|
|
56
|
+
decoded.p >= 1) {
|
|
57
|
+
return { kind: 'search', page: decoded.p };
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
// Falls through to malformed.
|
|
62
|
+
}
|
|
63
|
+
return { kind: 'malformed' };
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* The cursor for the page after this one, or `null` when there is none.
|
|
67
|
+
*
|
|
68
|
+
* **`null` has to mean exactly "no next page", never "probably not".** An agent paging until
|
|
69
|
+
* `nextCursor` is `null` must terminate, and must not make one extra call that returns an empty
|
|
70
|
+
* page. Derived from the response's own `total`/`page`/`pageSize` rather than from what was
|
|
71
|
+
* requested, since the server may legitimately return a smaller page than asked for.
|
|
72
|
+
*
|
|
73
|
+
* Returns `null` for any response whose paging members are missing or unusable: an unpageable answer
|
|
74
|
+
* is the end of the walk, which terminates, where an emitted cursor would loop.
|
|
75
|
+
*/
|
|
76
|
+
export function nextSearchCursor(response) {
|
|
77
|
+
if (typeof response !== 'object' || response === null)
|
|
78
|
+
return null;
|
|
79
|
+
const { total, page, pageSize } = response;
|
|
80
|
+
if (!Number.isFinite(total) || !Number.isFinite(page) || !Number.isFinite(pageSize))
|
|
81
|
+
return null;
|
|
82
|
+
if (pageSize <= 0 || page <= 0)
|
|
83
|
+
return null;
|
|
84
|
+
const seen = page * pageSize;
|
|
85
|
+
return seen < total ? encodeSearchCursor(page + 1) : null;
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=cursor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cursor.js","sourceRoot":"","sources":["../../src/tools/cursor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH;;;;;;;;;;GAUG;AACH,MAAM,MAAM,GAAG,QAAQ,CAAA;AAQvB,kEAAkE;AAClE,MAAM,UAAU,kBAAkB,CAAC,IAAY;IAC7C,OAAO,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAA;AACzG,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,YAAY,CAAC,MAA0B;IACrD,IAAI,MAAM,KAAK,SAAS,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,CAAA;IAEtF,IAAI,CAAC;QACH,MAAM,OAAO,GAAY,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAA;QAC3G,IACE,OAAO,OAAO,KAAK,QAAQ;YAC3B,OAAO,KAAK,IAAI;YACf,OAA2B,CAAC,CAAC,KAAK,YAAY;YAC/C,MAAM,CAAC,SAAS,CAAE,OAA2B,CAAC,CAAC,CAAC;YAC/C,OAAyB,CAAC,CAAC,IAAI,CAAC,EACjC,CAAC;YACD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAG,OAAyB,CAAC,CAAC,EAAE,CAAA;QAC/D,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,8BAA8B;IAChC,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,CAAA;AAC9B,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAAiB;IAChD,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,KAAK,IAAI;QAAE,OAAO,IAAI,CAAA;IAElE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,QAAmE,CAAA;IACrG,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAAE,OAAO,IAAI,CAAA;IAChG,IAAK,QAAmB,IAAI,CAAC,IAAK,IAAe,IAAI,CAAC;QAAE,OAAO,IAAI,CAAA;IAEnE,MAAM,IAAI,GAAI,IAAe,GAAI,QAAmB,CAAA;IACpD,OAAO,IAAI,GAAI,KAAgB,CAAC,CAAC,CAAC,kBAAkB,CAAE,IAAe,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;AACnF,CAAC"}
|
package/dist/tools/register.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
|
2
2
|
import type { ContentClient } from '../client.js';
|
|
3
3
|
import { type Session } from '../session.js';
|
|
4
4
|
/**
|
|
5
|
-
* The
|
|
5
|
+
* The ten tools.
|
|
6
6
|
*
|
|
7
7
|
* They are **task-shaped**, not endpoint-shaped: one per thing an agent does, never one per REST
|
|
8
8
|
* route or per entity kind. The API a management key reaches is roughly thirty endpoint groups, so a
|
|
@@ -21,6 +21,16 @@ export type ToolContext = {
|
|
|
21
21
|
session: Session;
|
|
22
22
|
/** The credential for the environment `content_transfer` imports into, when one is configured. */
|
|
23
23
|
target: ContentClient | null;
|
|
24
|
+
/**
|
|
25
|
+
* Reported by `content_whoami`, so an agent can read the build it is talking to rather than
|
|
26
|
+
* inferring it from which tools happen to exist.
|
|
27
|
+
*
|
|
28
|
+
* Passed in rather than imported from `server.ts`: that module already imports this one, so
|
|
29
|
+
* reaching back for the constant would make a module cycle — one that happens to work, since
|
|
30
|
+
* nothing here reads it at module scope, which is exactly the kind of thing that stops being true
|
|
31
|
+
* quietly.
|
|
32
|
+
*/
|
|
33
|
+
serverVersion: string;
|
|
24
34
|
};
|
|
25
35
|
export declare function registerTools(server: McpServer, context: ToolContext): void;
|
|
26
36
|
//# sourceMappingURL=register.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../../src/tools/register.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AAExE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAIjD,OAAO,EAA2D,KAAK,OAAO,EAAE,MAAM,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../../src/tools/register.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AAExE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAIjD,OAAO,EAA2D,KAAK,OAAO,EAAE,MAAM,eAAe,CAAA;AAKrG;;;;;;;;;;;;;;GAcG;AAEH,MAAM,MAAM,WAAW,GAAG;IACxB,MAAM,EAAE,aAAa,CAAA;IACrB,OAAO,EAAE,OAAO,CAAA;IAChB,kGAAkG;IAClG,MAAM,EAAE,aAAa,GAAG,IAAI,CAAA;IAC5B;;;;;;;;OAQG;IACH,aAAa,EAAE,MAAM,CAAA;CACtB,CAAA;AAID,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,GAAG,IAAI,CAsf3E"}
|
package/dist/tools/register.js
CHANGED
|
@@ -3,10 +3,12 @@ import { query } from '../client.js';
|
|
|
3
3
|
import { ContentApiError } from '../errors.js';
|
|
4
4
|
import { routesFor, withId, WRITABLE_KINDS } from '../routes.js';
|
|
5
5
|
import { SCOPE_AUTHORING, SCOPE_PUBLISH, SCOPE_READ, SCOPE_WRITE } from '../session.js';
|
|
6
|
+
import { decodeCursor, nextSearchCursor } from './cursor.js';
|
|
6
7
|
import { fail, guard, ok } from './result.js';
|
|
8
|
+
import { describeSession } from './whoami.js';
|
|
7
9
|
const KIND = z.enum(WRITABLE_KINDS);
|
|
8
10
|
export function registerTools(server, context) {
|
|
9
|
-
const { client, session, target } = context;
|
|
11
|
+
const { client, session, target, serverVersion } = context;
|
|
10
12
|
// Everything below is gated on a scope, and an absent tool is the point: an agent that cannot see
|
|
11
13
|
// a tool will not plan around it, where a tool that is present and always 403s costs it a turn
|
|
12
14
|
// and a re-plan (§4).
|
|
@@ -14,6 +16,43 @@ export function registerTools(server, context) {
|
|
|
14
16
|
const canAuthor = session.has(SCOPE_AUTHORING);
|
|
15
17
|
const canPublish = session.has(SCOPE_PUBLISH);
|
|
16
18
|
const canTransfer = session.has(SCOPE_WRITE);
|
|
19
|
+
// Derived from the same four booleans the registrations below are gated on, in the same pass —
|
|
20
|
+
// never a separate tool→scope table, which would be a copy of a fact those `if` blocks already
|
|
21
|
+
// state and would go stale the first time a tool moved scope (spec #792; this codebase has had
|
|
22
|
+
// that exact failure twice, and both times the forgotten copy was the reader).
|
|
23
|
+
const withheld = [
|
|
24
|
+
...(canRead
|
|
25
|
+
? []
|
|
26
|
+
: ['content_describe', 'content_find', 'content_get', 'content_topology', 'content_operation_status'].map((tool) => ({ tool, requires: SCOPE_READ }))),
|
|
27
|
+
...(canAuthor
|
|
28
|
+
? []
|
|
29
|
+
: [
|
|
30
|
+
{ tool: 'content_write', requires: SCOPE_AUTHORING },
|
|
31
|
+
{ tool: 'content_delete', requires: SCOPE_AUTHORING },
|
|
32
|
+
]),
|
|
33
|
+
...(canPublish ? [] : [{ tool: 'content_publish', requires: SCOPE_PUBLISH }]),
|
|
34
|
+
...(canTransfer ? [] : [{ tool: 'content_transfer', requires: SCOPE_WRITE }]),
|
|
35
|
+
];
|
|
36
|
+
// Gated on NOTHING, and registered before every scope block so that is visible at a glance.
|
|
37
|
+
//
|
|
38
|
+
// It mirrors the server route's own scope exemption (ContentManagementRouteScopes.AuthenticatedOnly)
|
|
39
|
+
// and for the same reason spec #511 gave for it: a key minted with only `publish` must be able to
|
|
40
|
+
// discover that that is all it holds, which it could not if the answer itself required `read`. The
|
|
41
|
+
// MCP surface made that worse than the HTTP one — such a key watches five tools vanish with nothing
|
|
42
|
+
// to ask about it. It also costs nothing: `resolveSession` already called `/whoami` at startup, so
|
|
43
|
+
// this answers from memory and issues no request.
|
|
44
|
+
server.registerTool('content_whoami', {
|
|
45
|
+
title: 'Where am I scoped?',
|
|
46
|
+
description: 'What this credential is: the organization and authoring environment it is bound to, the ' +
|
|
47
|
+
'role it acts as, its scopes, this server\'s version, and which tools were withheld and the ' +
|
|
48
|
+
'scope each needs. Read it before concluding that something does not exist — every result ' +
|
|
49
|
+
'from this server is scoped to one environment, so an empty list means nothing matched ' +
|
|
50
|
+
'there, not that nothing exists anywhere.',
|
|
51
|
+
inputSchema: {},
|
|
52
|
+
// openWorldHint is false here and true on every other tool: this one reaches no external
|
|
53
|
+
// system at all, answering from the credential resolved when the server started.
|
|
54
|
+
annotations: { readOnlyHint: true, openWorldHint: false },
|
|
55
|
+
}, async () => ok(describeSession(session, withheld, serverVersion)));
|
|
17
56
|
if (canRead) {
|
|
18
57
|
server.registerTool('content_describe', {
|
|
19
58
|
title: 'Describe what can exist here',
|
|
@@ -35,7 +74,8 @@ export function registerTools(server, context) {
|
|
|
35
74
|
wanted.has('contracts') ? client.request('GET', '/contracts') : undefined,
|
|
36
75
|
wanted.has('templates') ? client.request('GET', '/templates') : undefined,
|
|
37
76
|
]);
|
|
38
|
-
|
|
77
|
+
const result = { fieldTypes, contracts, templates };
|
|
78
|
+
return ok(result, readContext(session, result));
|
|
39
79
|
}));
|
|
40
80
|
server.registerTool('content_find', {
|
|
41
81
|
title: 'Find entities',
|
|
@@ -54,13 +94,41 @@ export function registerTools(server, context) {
|
|
|
54
94
|
// Two listings, one tool, because both answer "what is already here" and an agent asking
|
|
55
95
|
// that should not have to know which of them can filter. The components listing is the
|
|
56
96
|
// only one that takes a query at all; /items is a flat inventory across every kind.
|
|
97
|
+
//
|
|
98
|
+
// They also PAGE differently, and not merely by parameter name: /items is cursor-paged,
|
|
99
|
+
// /components is offset-paged (page/pageSize, answering total) and returns no cursor at
|
|
100
|
+
// all. This tool's schema promises `limit` and `cursor` for both, and the search branch
|
|
101
|
+
// used to forward neither — so an agent paginating a search got page one forever, with
|
|
102
|
+
// nothing saying its parameters had been discarded (spec #793). `cursor.ts` normalizes the
|
|
103
|
+
// two into one contract; the branch an agent is on is never its problem.
|
|
104
|
+
const decoded = decodeCursor(cursor);
|
|
105
|
+
if (decoded.kind === 'malformed') {
|
|
106
|
+
return fail('That cursor is not one this tool issued, or it has been altered. Drop it to start ' +
|
|
107
|
+
'from the first page, or pass the exact nextCursor from a previous call.');
|
|
108
|
+
}
|
|
57
109
|
if (search !== undefined || externalId !== undefined) {
|
|
58
110
|
if (kind !== undefined && kind !== 'component') {
|
|
59
111
|
return fail('search and externalId filter components only; drop them, or pass kind: "component".');
|
|
60
112
|
}
|
|
61
|
-
|
|
113
|
+
if (decoded.kind === 'passthrough' && cursor !== undefined) {
|
|
114
|
+
return fail('That cursor came from the inventory listing and cannot page a components search. ' +
|
|
115
|
+
'Drop search/externalId to keep paging the inventory, or drop the cursor to search ' +
|
|
116
|
+
'from the first page.');
|
|
117
|
+
}
|
|
118
|
+
const page = decoded.kind === 'search' ? decoded.page : 1;
|
|
119
|
+
const found = await client.request('GET',
|
|
120
|
+
// `page` only once past the first, so a search with no paging asked for is the exact
|
|
121
|
+
// request this tool has always sent.
|
|
122
|
+
`/components${query({ search, externalId, page: page > 1 ? page : undefined, pageSize: limit })}`);
|
|
123
|
+
return ok({ ...found, nextCursor: nextSearchCursor(found) }, readContext(session, found));
|
|
124
|
+
}
|
|
125
|
+
if (decoded.kind === 'search') {
|
|
126
|
+
return fail('That cursor came from a components search and cannot page the inventory listing. ' +
|
|
127
|
+
'Keep search/externalId to continue that search, or drop the cursor to list from the ' +
|
|
128
|
+
'first page.');
|
|
62
129
|
}
|
|
63
|
-
|
|
130
|
+
const listed = await client.request('GET', `/items${query({ kind, limit, cursor })}`);
|
|
131
|
+
return ok(listed, readContext(session, listed));
|
|
64
132
|
}));
|
|
65
133
|
server.registerTool('content_get', {
|
|
66
134
|
title: 'Read one entity',
|
|
@@ -76,7 +144,21 @@ export function registerTools(server, context) {
|
|
|
76
144
|
(routes.list ? ` (kind: "${kind}")` : '') +
|
|
77
145
|
' instead.');
|
|
78
146
|
}
|
|
79
|
-
|
|
147
|
+
try {
|
|
148
|
+
return ok(await client.request('GET', withId(routes.readOne, id)), session.contextLine());
|
|
149
|
+
}
|
|
150
|
+
catch (error) {
|
|
151
|
+
// A 404 here always means "not found *in this key's environment*", and the relayed body
|
|
152
|
+
// cannot say so — it is the server's answer about a route, not about a binding. So the
|
|
153
|
+
// binding is ADDED after it, never substituted for it: §3's verbatim relay is what closes
|
|
154
|
+
// the agent's try → read → fix loop, and this is the same shape `errors.ts` already uses
|
|
155
|
+
// to add a `Request id:` line without touching the body.
|
|
156
|
+
if (error instanceof ContentApiError && error.status === 404) {
|
|
157
|
+
return fail(`${error.message}\n${session.contextLine()} — not found in this environment, which is ` +
|
|
158
|
+
'the only one this key can read.');
|
|
159
|
+
}
|
|
160
|
+
throw error;
|
|
161
|
+
}
|
|
80
162
|
}));
|
|
81
163
|
// Its own tool rather than another `include` value on content_describe (spec 748): describe
|
|
82
164
|
// answers "what can this environment hold", this answers "where does it sit", and an agent
|
|
@@ -97,7 +179,7 @@ export function registerTools(server, context) {
|
|
|
97
179
|
annotations: { readOnlyHint: true, openWorldHint: true },
|
|
98
180
|
}, async () => guard(async () => {
|
|
99
181
|
try {
|
|
100
|
-
return ok(await client.request('GET', '/topology'));
|
|
182
|
+
return ok(await client.request('GET', '/topology'), session.contextLine());
|
|
101
183
|
}
|
|
102
184
|
catch (error) {
|
|
103
185
|
// The one refusal worth rewording, because its remedy is not in the body: routing
|
|
@@ -208,7 +290,7 @@ export function registerTools(server, context) {
|
|
|
208
290
|
'result — for a plan, that result is the plan itself.',
|
|
209
291
|
inputSchema: { operationId: z.string() },
|
|
210
292
|
annotations: { readOnlyHint: true, openWorldHint: true },
|
|
211
|
-
}, async ({ operationId }) => guard(async () => ok(await client.request('GET', `/operations/${encodeURIComponent(operationId)}`))));
|
|
293
|
+
}, async ({ operationId }) => guard(async () => ok(await client.request('GET', `/operations/${encodeURIComponent(operationId)}`), session.contextLine())));
|
|
212
294
|
}
|
|
213
295
|
if (canTransfer) {
|
|
214
296
|
server.registerTool('content_transfer', {
|
|
@@ -216,7 +298,11 @@ export function registerTools(server, context) {
|
|
|
216
298
|
description: 'Export this environment (or a set of roots) as a bundle, and — when a target key is ' +
|
|
217
299
|
'configured — import it into that target atomically. This is the one operation bundles ' +
|
|
218
300
|
'are uniquely good at: forty per-entity writes are forty transactions, and one import is ' +
|
|
219
|
-
'one. The bundle is produced and consumed by the server; nothing here builds it
|
|
301
|
+
'one. The bundle is produced and consumed by the server; nothing here builds it.\n\n' +
|
|
302
|
+
'Importing is a job, like publishing: with apply, this returns the plan and an ' +
|
|
303
|
+
'operationId, and the import is NOT finished when this returns. Poll it with ' +
|
|
304
|
+
'content_operation_status until it succeeds or fails — a failed run says why, including ' +
|
|
305
|
+
'every invalid document when that is the reason.',
|
|
220
306
|
inputSchema: {
|
|
221
307
|
roots: z.array(z.record(z.string(), z.unknown())).optional(),
|
|
222
308
|
wholeEnvironment: z.boolean().optional(),
|
|
@@ -259,15 +345,80 @@ export function registerTools(server, context) {
|
|
|
259
345
|
// The plan's own items are echoed back as the selection. `items[]` selects what is
|
|
260
346
|
// written (spec #623), so sending the plan unchanged is "apply everything this plan
|
|
261
347
|
// describes" — and it is the plan, not this code, that decided what that is.
|
|
262
|
-
|
|
348
|
+
//
|
|
349
|
+
// Spec 775-management-import-async-job: this answers 202 `{ id, status }` and the import
|
|
350
|
+
// runs as a job. Returned as `operation` rather than polled here, matching content_publish
|
|
351
|
+
// in this same file — the agent polls with content_operation_status. The naming is
|
|
352
|
+
// load-bearing: returning a kick-off envelope under `result` is precisely how an agent
|
|
353
|
+
// would report a finished import that had not run yet.
|
|
354
|
+
const selection = (plan.items ?? []).map((item) => ({ kind: item.kind, id: item.id }));
|
|
355
|
+
// `items[]` SELECTS what is written (spec #623), so an empty selection is not "import
|
|
356
|
+
// everything" — it is an import that writes nothing and answers `succeeded`, which an agent
|
|
357
|
+
// then reports as content that exists. Exactly the failure `toPublishItem` below was written
|
|
358
|
+
// to prevent on the publish path; this path had no guard at all (spec #793).
|
|
359
|
+
//
|
|
360
|
+
// Refused BEFORE the call, not after on the operation's result: starting a job that provably
|
|
361
|
+
// writes nothing spends a write quota and leaves an operation record implying an import
|
|
362
|
+
// happened. And `fail()` rather than a success carrying a warning, because a
|
|
363
|
+
// successful-looking result indistinguishable from a real import is the whole defect.
|
|
364
|
+
//
|
|
365
|
+
// Note an empty plan is not necessarily the server being wrong: a bundle whose every item
|
|
366
|
+
// already matches the target legitimately plans to nothing. What is wrong is calling that an
|
|
367
|
+
// import — so this says which of the two happened.
|
|
368
|
+
if (selection.length === 0) {
|
|
369
|
+
return fail('Nothing would be imported. The plan selected 0 items, and items[] is what an import ' +
|
|
370
|
+
'writes — so this would start a job, import nothing, and report success. Nothing was ' +
|
|
371
|
+
'sent. If the target already matches the source, that is the plan saying so.');
|
|
372
|
+
}
|
|
373
|
+
const operation = await target.request('POST', '/import', {
|
|
263
374
|
bundle,
|
|
264
375
|
identityMode: mode,
|
|
265
|
-
items:
|
|
376
|
+
items: selection,
|
|
266
377
|
});
|
|
267
|
-
return ok({ plan,
|
|
378
|
+
return ok({ plan, operation, pollWith: 'content_operation_status' });
|
|
268
379
|
}));
|
|
269
380
|
}
|
|
270
381
|
}
|
|
382
|
+
/**
|
|
383
|
+
* The context line a read result carries, and the stronger sentence an empty one gets.
|
|
384
|
+
*
|
|
385
|
+
* Spec #792: an agent could not tell **"none exist"** from **"none in this key's scope"**, because
|
|
386
|
+
* neither `[]` nor a relayed `404` named the environment it was answered in. That is the same
|
|
387
|
+
* ambiguity spec #790 found one layer out, where it cost a long misdiagnosis — an empty array that
|
|
388
|
+
* meant "nothing selected" read as "nothing exists".
|
|
389
|
+
*
|
|
390
|
+
* An empty read stays a **success**. A brand-new environment genuinely has no Contracts, so marking
|
|
391
|
+
* it an error would send an agent hunting a fault that does not exist; what was missing is what the
|
|
392
|
+
* emptiness is *of*.
|
|
393
|
+
*/
|
|
394
|
+
function readContext(session, result) {
|
|
395
|
+
return looksEmpty(result)
|
|
396
|
+
? `${session.contextLine()} 0 of 0 — this key reads only this environment.`
|
|
397
|
+
: session.contextLine();
|
|
398
|
+
}
|
|
399
|
+
/**
|
|
400
|
+
* Whether a response carries no content at all.
|
|
401
|
+
*
|
|
402
|
+
* Deliberately conservative: it answers `false` whenever it is unsure, because claiming "0 of 0"
|
|
403
|
+
* about a result that did contain something would be a new way of saying the wrong thing. `null` and
|
|
404
|
+
* `undefined` members are ignored rather than counted (`{items: [], nextCursor: null}` is empty; so
|
|
405
|
+
* is a `content_describe` narrowed by `include` to one empty list).
|
|
406
|
+
*/
|
|
407
|
+
function looksEmpty(result) {
|
|
408
|
+
if (Array.isArray(result))
|
|
409
|
+
return result.length === 0;
|
|
410
|
+
if (typeof result !== 'object' || result === null)
|
|
411
|
+
return false;
|
|
412
|
+
// Both listings answer with an `items` array, and that member alone decides for them. Checked
|
|
413
|
+
// before the general rule below because a paged `/components` body also carries `total`, `page`
|
|
414
|
+
// and `pageSize` — numbers, which are not evidence of content either way, and which the general
|
|
415
|
+
// rule would read as "this result contains something".
|
|
416
|
+
const items = result.items;
|
|
417
|
+
if (Array.isArray(items))
|
|
418
|
+
return items.length === 0;
|
|
419
|
+
const present = Object.values(result).filter((value) => value !== undefined && value !== null);
|
|
420
|
+
return present.length > 0 && present.every((value) => Array.isArray(value) && value.length === 0);
|
|
421
|
+
}
|
|
271
422
|
/**
|
|
272
423
|
* Normalizes one execute item.
|
|
273
424
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"register.js","sourceRoot":"","sources":["../../src/tools/register.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"register.js","sourceRoot":"","sources":["../../src/tools/register.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAA;AACpC,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAChE,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,UAAU,EAAE,WAAW,EAAgB,MAAM,eAAe,CAAA;AACrG,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAC5D,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,aAAa,CAAA;AAC7C,OAAO,EAAE,eAAe,EAAqB,MAAM,aAAa,CAAA;AAmChE,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAA;AAEnC,MAAM,UAAU,aAAa,CAAC,MAAiB,EAAE,OAAoB;IACnE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,CAAA;IAE1D,kGAAkG;IAClG,+FAA+F;IAC/F,sBAAsB;IACtB,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAA;IACvC,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAA;IAC9C,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAA;IAC7C,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAA;IAE5C,+FAA+F;IAC/F,+FAA+F;IAC/F,+FAA+F;IAC/F,+EAA+E;IAC/E,MAAM,QAAQ,GAAmB;QAC/B,GAAG,CAAC,OAAO;YACT,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,CAAC,kBAAkB,EAAE,cAAc,EAAE,aAAa,EAAE,kBAAkB,EAAE,0BAA0B,CAAC,CAAC,GAAG,CACrG,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,CAC3C,CAAC;QACN,GAAG,CAAC,SAAS;YACX,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC;gBACE,EAAE,IAAI,EAAE,eAAe,EAAE,QAAQ,EAAE,eAAe,EAAE;gBACpD,EAAE,IAAI,EAAE,gBAAgB,EAAE,QAAQ,EAAE,eAAe,EAAE;aACtD,CAAC;QACN,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,iBAAiB,EAAE,QAAQ,EAAE,aAAa,EAAE,CAAC,CAAC;QAC7E,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,kBAAkB,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC,CAAC;KAC9E,CAAA;IAED,4FAA4F;IAC5F,EAAE;IACF,qGAAqG;IACrG,kGAAkG;IAClG,mGAAmG;IACnG,oGAAoG;IACpG,mGAAmG;IACnG,kDAAkD;IAClD,MAAM,CAAC,YAAY,CACjB,gBAAgB,EAChB;QACE,KAAK,EAAE,oBAAoB;QAC3B,WAAW,EACT,0FAA0F;YAC1F,6FAA6F;YAC7F,2FAA2F;YAC3F,wFAAwF;YACxF,0CAA0C;QAC5C,WAAW,EAAE,EAAE;QACf,yFAAyF;QACzF,iFAAiF;QACjF,WAAW,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE;KAC1D,EACD,KAAK,IAAI,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,OAAO,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAC,CAClE,CAAA;IAED,IAAI,OAAO,EAAE,CAAC;QACZ,MAAM,CAAC,YAAY,CACjB,kBAAkB,EAClB;YACE,KAAK,EAAE,8BAA8B;YACrC,WAAW,EACT,sFAAsF;gBACtF,wFAAwF;gBACxF,wFAAwF;gBACxF,mDAAmD;YACrD,WAAW,EAAE;gBACX,OAAO,EAAE,CAAC;qBACP,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,YAAY,EAAE,WAAW,EAAE,WAAW,CAAC,CAAC,CAAC;qBACvD,QAAQ,EAAE;qBACV,QAAQ,CAAC,wBAAwB,CAAC;aACtC;YACD,WAAW,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE;SACzD,EACD,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CACpB,KAAK,CAAC,KAAK,IAAI,EAAE;YACf,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,OAAO,IAAI,CAAC,YAAY,EAAE,WAAW,EAAE,WAAW,CAAC,CAAC,CAAA;YAC3E,MAAM,CAAC,UAAU,EAAE,SAAS,EAAE,SAAS,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;gBAC3D,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC,SAAS;gBAC5E,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,SAAS;gBACzE,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,SAAS;aAC1E,CAAC,CAAA;YAEF,MAAM,MAAM,GAAG,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,CAAA;YACnD,OAAO,EAAE,CAAC,MAAM,EAAE,WAAW,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAA;QACjD,CAAC,CAAC,CACL,CAAA;QAED,MAAM,CAAC,YAAY,CACjB,cAAc,EACd;YACE,KAAK,EAAE,eAAe;YACtB,WAAW,EACT,kFAAkF;gBAClF,qFAAqF;gBACrF,qCAAqC;YACvC,WAAW,EAAE;gBACX,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,iGAAiG,CAAC;gBACvI,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,oCAAoC,CAAC;gBAC5E,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,+BAA+B,CAAC;gBAC3E,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE;gBAClD,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,qCAAqC,CAAC;aAC9E;YACD,WAAW,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE;SACzD,EACD,KAAK,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,CACpD,KAAK,CAAC,KAAK,IAAI,EAAE;YACf,yFAAyF;YACzF,uFAAuF;YACvF,oFAAoF;YACpF,EAAE;YACF,wFAAwF;YACxF,wFAAwF;YACxF,wFAAwF;YACxF,uFAAuF;YACvF,2FAA2F;YAC3F,yEAAyE;YACzE,MAAM,OAAO,GAAG,YAAY,CAAC,MAAM,CAAC,CAAA;YACpC,IAAI,OAAO,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;gBACjC,OAAO,IAAI,CACT,oFAAoF;oBAClF,yEAAyE,CAC5E,CAAA;YACH,CAAC;YAED,IAAI,MAAM,KAAK,SAAS,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;gBACrD,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,WAAW,EAAE,CAAC;oBAC/C,OAAO,IAAI,CAAC,qFAAqF,CAAC,CAAA;gBACpG,CAAC;gBAED,IAAI,OAAO,CAAC,IAAI,KAAK,aAAa,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;oBAC3D,OAAO,IAAI,CACT,mFAAmF;wBACjF,oFAAoF;wBACpF,sBAAsB,CACzB,CAAA;gBACH,CAAC;gBAED,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;gBACzD,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,OAAO,CAChC,KAAK;gBACL,qFAAqF;gBACrF,qCAAqC;gBACrC,cAAc,KAAK,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,EAAE,CAClG,CAAA;gBAED,OAAO,EAAE,CACP,EAAE,GAAI,KAAiC,EAAE,UAAU,EAAE,gBAAgB,CAAC,KAAK,CAAC,EAAE,EAC9E,WAAW,CAAC,OAAO,EAAE,KAAK,CAAC,CAC5B,CAAA;YACH,CAAC;YAED,IAAI,OAAO,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAC9B,OAAO,IAAI,CACT,mFAAmF;oBACjF,sFAAsF;oBACtF,aAAa,CAChB,CAAA;YACH,CAAC;YAED,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,SAAS,KAAK,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAA;YACrF,OAAO,EAAE,CAAC,MAAM,EAAE,WAAW,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAA;QACjD,CAAC,CAAC,CACL,CAAA;QAED,MAAM,CAAC,YAAY,CACjB,aAAa,EACb;YACE,KAAK,EAAE,iBAAiB;YACxB,WAAW,EACT,0FAA0F;gBAC1F,uFAAuF;gBACvF,2CAA2C;YAC7C,WAAW,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE;YAC3C,WAAW,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE;SACzD,EACD,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE,CACrB,KAAK,CAAC,KAAK,IAAI,EAAE;YACf,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC,CAAA;YAC9B,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBACpB,OAAO,IAAI,CACT,GAAG,MAAM,CAAC,KAAK,0DAA0D;oBACvE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,YAAY,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;oBACzC,WAAW,CACd,CAAA;YACH,CAAC;YAED,IAAI,CAAC;gBACH,OAAO,EAAE,CAAC,MAAM,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,WAAW,EAAE,CAAC,CAAA;YAC3F,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,wFAAwF;gBACxF,uFAAuF;gBACvF,0FAA0F;gBAC1F,yFAAyF;gBACzF,yDAAyD;gBACzD,IAAI,KAAK,YAAY,eAAe,IAAI,KAAK,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;oBAC7D,OAAO,IAAI,CACT,GAAG,KAAK,CAAC,OAAO,KAAK,OAAO,CAAC,WAAW,EAAE,6CAA6C;wBACrF,iCAAiC,CACpC,CAAA;gBACH,CAAC;gBACD,MAAM,KAAK,CAAA;YACb,CAAC;QACH,CAAC,CAAC,CACL,CAAA;QAED,4FAA4F;QAC5F,2FAA2F;QAC3F,2FAA2F;QAC3F,6FAA6F;QAC7F,uEAAuE;QACvE,MAAM,CAAC,YAAY,CACjB,kBAAkB,EAClB;YACE,KAAK,EAAE,6BAA6B;YACpC,WAAW,EACT,yFAAyF;gBACzF,uFAAuF;gBACvF,qFAAqF;gBACrF,mFAAmF;gBACnF,gFAAgF;gBAChF,qFAAqF;gBACrF,qFAAqF;gBACrF,4EAA4E;YAC9E,WAAW,EAAE,EAAE;YACf,WAAW,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE;SACzD,EACD,KAAK,IAAI,EAAE,CACT,KAAK,CAAC,KAAK,IAAI,EAAE;YACf,IAAI,CAAC;gBACH,OAAO,EAAE,CAAC,MAAM,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,WAAW,CAAC,EAAE,OAAO,CAAC,WAAW,EAAE,CAAC,CAAA;YAC5E,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,kFAAkF;gBAClF,sFAAsF;gBACtF,qFAAqF;gBACrF,IAAI,KAAK,YAAY,eAAe,IAAI,KAAK,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;oBAC7D,OAAO,IAAI,CACT,GAAG,MAAM,CAAC,OAAO,+DAA+D;wBAC9E,6EAA6E;wBAC7E,6CAA6C,CAChD,CAAA;gBACH,CAAC;gBACD,MAAM,KAAK,CAAA;YACb,CAAC;QACH,CAAC,CAAC,CACL,CAAA;IACH,CAAC;IAED,IAAI,SAAS,EAAE,CAAC;QACd,MAAM,CAAC,YAAY,CACjB,eAAe,EACf;YACE,KAAK,EAAE,4BAA4B;YACnC,WAAW,EACT,0FAA0F;gBAC1F,yFAAyF;gBACzF,2FAA2F;gBAC3F,gDAAgD;gBAChD,yFAAyF;gBACzF,0FAA0F;gBAC1F,2FAA2F;gBAC3F,+BAA+B;YACjC,WAAW,EAAE;gBACX,IAAI,EAAE,IAAI;gBACV,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,iBAAiB,CAAC;gBACrD,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,mDAAmD,CAAC;aACzG;YACD,WAAW,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE;SACxG,EACD,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAC9B,KAAK,CAAC,KAAK,IAAI,EAAE;YACf,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC,CAAA;YAE9B,IAAI,CAAC,EAAE,EAAE,CAAC;gBACR,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;oBACnB,OAAO,IAAI,CAAC,GAAG,MAAM,CAAC,KAAK,qEAAqE,CAAC,CAAA;gBACnG,CAAC;gBAED,OAAO,EAAE,CAAC,MAAM,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,WAAW,EAAE,CAAC,CAAA;YACxF,CAAC;YAED,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;gBACnB,OAAO,IAAI,CAAC,GAAG,MAAM,CAAC,KAAK,kCAAkC,CAAC,CAAA;YAChE,CAAC;YAED,yFAAyF;YACzF,6EAA6E;YAC7E,OAAO,EAAE,CACP,MAAM,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,OAAO,CAAC,EACnF,OAAO,CAAC,WAAW,EAAE,CACtB,CAAA;QACH,CAAC,CAAC,CACL,CAAA;QAED,MAAM,CAAC,YAAY,CACjB,gBAAgB,EAChB;YACE,KAAK,EAAE,kBAAkB;YACzB,WAAW,EACT,mFAAmF;gBACnF,mFAAmF;gBACnF,6DAA6D;YAC/D,WAAW,EAAE;gBACX,IAAI,EAAE,IAAI;gBACV,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE;gBACd,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,iCAAiC,CAAC;aACjE;YACD,WAAW,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE;SACvG,EACD,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAC9B,KAAK,CAAC,KAAK,IAAI,EAAE;YACf,sFAAsF;YACtF,wFAAwF;YACxF,oCAAoC;YACpC,IAAI,CAAC,OAAO;gBAAE,OAAO,IAAI,CAAC,6DAA6D,CAAC,CAAA;YAExF,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC,CAAA;YAC9B,IAAI,CAAC,MAAM,CAAC,MAAM;gBAAE,OAAO,IAAI,CAAC,GAAG,MAAM,CAAC,KAAK,sCAAsC,CAAC,CAAA;YAEtF,MAAM,MAAM,CAAC,OAAO,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAA;YACzD,OAAO,EAAE,CAAC,WAAW,MAAM,CAAC,KAAK,IAAI,EAAE,GAAG,EAAE,OAAO,CAAC,WAAW,EAAE,CAAC,CAAA;QACpE,CAAC,CAAC,CACL,CAAA;IACH,CAAC;IAED,IAAI,UAAU,EAAE,CAAC;QACf,MAAM,CAAC,YAAY,CACjB,iBAAiB,EACjB;YACE,KAAK,EAAE,iBAAiB;YACxB,WAAW,EACT,0FAA0F;gBAC1F,sFAAsF;gBACtF,0FAA0F;gBAC1F,oFAAoF;YACtF,WAAW,EAAE;gBACX,KAAK,EAAE,CAAC;qBACL,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;qBACxC,QAAQ,EAAE;qBACV,QAAQ,CAAC,yDAAyD,CAAC;gBACtE,KAAK,EAAE,CAAC;qBACL,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;qBACxC,QAAQ,EAAE;qBACV,QAAQ,CACP,sFAAsF;oBACpF,kDAAkD,CACrD;gBACH,qBAAqB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,yDAAyD,CAAC;aACjH;YACD,WAAW,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE;SACzG,EACD,KAAK,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,qBAAqB,EAAE,EAAE,EAAE,CAChD,KAAK,CAAC,KAAK,IAAI,EAAE;YACf,IAAI,CAAC,KAAK,KAAK,SAAS,CAAC,KAAK,CAAC,KAAK,KAAK,SAAS,CAAC,EAAE,CAAC;gBACpD,OAAO,IAAI,CAAC,4DAA4D,CAAC,CAAA;YAC3E,CAAC;YAED,IAAI,KAAK,EAAE,CAAC;gBACV,OAAO,EAAE,CACP,MAAM,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,eAAe,EAAE,EAAE,KAAK,EAAE,qBAAqB,EAAE,CAAC,EAC/E,OAAO,CAAC,WAAW,EAAE,CACtB,CAAA;YACH,CAAC;YAED,OAAO,EAAE,CACP,MAAM,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,UAAU,EAAE;gBACvC,KAAK,EAAE,KAAM,CAAC,GAAG,CAAC,aAAa,CAAC;gBAChC,qBAAqB;aACtB,CAAC,EACF,OAAO,CAAC,WAAW,EAAE,CACtB,CAAA;QACH,CAAC,CAAC,CACL,CAAA;IACH,CAAC;IAED,IAAI,OAAO,EAAE,CAAC;QACZ,MAAM,CAAC,YAAY,CACjB,0BAA0B,EAC1B;YACE,KAAK,EAAE,aAAa;YACpB,WAAW,EACT,oFAAoF;gBACpF,sDAAsD;YACxD,WAAW,EAAE,EAAE,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE;YACxC,WAAW,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE;SACzD,EACD,KAAK,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,CACxB,KAAK,CAAC,KAAK,IAAI,EAAE,CACf,EAAE,CACA,MAAM,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,eAAe,kBAAkB,CAAC,WAAW,CAAC,EAAE,CAAC,EAC7E,OAAO,CAAC,WAAW,EAAE,CACtB,CACF,CACJ,CAAA;IACH,CAAC;IAED,IAAI,WAAW,EAAE,CAAC;QAChB,MAAM,CAAC,YAAY,CACjB,kBAAkB,EAClB;YACE,KAAK,EAAE,mCAAmC;YAC1C,WAAW,EACT,sFAAsF;gBACtF,wFAAwF;gBACxF,0FAA0F;gBAC1F,qFAAqF;gBACrF,gFAAgF;gBAChF,8EAA8E;gBAC9E,yFAAyF;gBACzF,iDAAiD;YACnD,WAAW,EAAE;gBACX,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,QAAQ,EAAE;gBAC5D,gBAAgB,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;gBACxC,KAAK,EAAE,CAAC;qBACL,OAAO,EAAE;qBACT,QAAQ,EAAE;qBACV,QAAQ,CAAC,8EAA8E,CAAC;gBAC3F,0FAA0F;gBAC1F,wFAAwF;gBACxF,0FAA0F;gBAC1F,mFAAmF;gBACnF,2FAA2F;gBAC3F,sFAAsF;gBACtF,8EAA8E;gBAC9E,YAAY,EAAE,CAAC;qBACZ,IAAI,CAAC,CAAC,UAAU,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC;qBACzC,QAAQ,EAAE;qBACV,QAAQ,CACP,wEAAwE;oBACtE,qFAAqF;oBACrF,mFAAmF;oBACnF,2EAA2E;oBAC3E,mFAAmF;oBACnF,qFAAqF;oBACrF,eAAe,CAClB;aACJ;YACD,WAAW,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE;SACxG,EACD,KAAK,EAAE,EAAE,KAAK,EAAE,gBAAgB,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,EAAE,CACzD,KAAK,CAAC,KAAK,IAAI,EAAE;YACf,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,SAAS,EAAE;gBACrD,KAAK;gBACL,gBAAgB,EAAE,gBAAgB,IAAI,KAAK,KAAK,SAAS;aAC1D,CAAC,CAAA;YAEF,IAAI,CAAC,KAAK;gBAAE,OAAO,EAAE,CAAC,MAAM,CAAC,CAAA;YAC7B,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,OAAO,IAAI,CACT,qFAAqF;oBACnF,uDAAuD,CAC1D,CAAA;YACH,CAAC;YAED,MAAM,IAAI,GAAG,YAAY,IAAI,YAAY,CAAA;YACzC,MAAM,IAAI,GAAG,CAAC,MAAM,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,cAAc,EAAE,EAAE,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CAEzF,CAAA;YAED,mFAAmF;YACnF,oFAAoF;YACpF,6EAA6E;YAC7E,EAAE;YACF,yFAAyF;YACzF,2FAA2F;YAC3F,mFAAmF;YACnF,uFAAuF;YACvF,uDAAuD;YACvD,MAAM,SAAS,GAAG,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,CAAA;YAEtF,sFAAsF;YACtF,4FAA4F;YAC5F,6FAA6F;YAC7F,6EAA6E;YAC7E,EAAE;YACF,6FAA6F;YAC7F,wFAAwF;YACxF,6EAA6E;YAC7E,sFAAsF;YACtF,EAAE;YACF,0FAA0F;YAC1F,6FAA6F;YAC7F,mDAAmD;YACnD,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC3B,OAAO,IAAI,CACT,sFAAsF;oBACpF,sFAAsF;oBACtF,6EAA6E,CAChF,CAAA;YACH,CAAC;YAED,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,SAAS,EAAE;gBACxD,MAAM;gBACN,YAAY,EAAE,IAAI;gBAClB,KAAK,EAAE,SAAS;aACjB,CAAC,CAAA;YAEF,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,0BAA0B,EAAE,CAAC,CAAA;QACtE,CAAC,CAAC,CACL,CAAA;IACH,CAAC;AACH,CAAC;AAED;;;;;;;;;;;GAWG;AACH,SAAS,WAAW,CAAC,OAAgB,EAAE,MAAe;IACpD,OAAO,UAAU,CAAC,MAAM,CAAC;QACvB,CAAC,CAAC,GAAG,OAAO,CAAC,WAAW,EAAE,iDAAiD;QAC3E,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,CAAA;AAC3B,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,UAAU,CAAC,MAAe;IACjC,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;QAAE,OAAO,MAAM,CAAC,MAAM,KAAK,CAAC,CAAA;IACrD,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI;QAAE,OAAO,KAAK,CAAA;IAE/D,8FAA8F;IAC9F,gGAAgG;IAChG,gGAAgG;IAChG,uDAAuD;IACvD,MAAM,KAAK,GAAI,MAA8B,CAAC,KAAK,CAAA;IACnD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC,CAAA;IAEnD,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,MAAiC,CAAC,CAAC,MAAM,CACrE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,CACjD,CAAA;IAED,OAAO,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,OAAO,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAA;AACnG,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,SAAS,aAAa,CAAC,IAA6B;IAClD,OAAO;QACL,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,EAAE,EAAE,IAAI,CAAC,EAAE;QACX,aAAa,EAAE,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,iBAAiB;QAC3D,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,IAAI;KAC9B,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { Session } from '../session.js';
|
|
2
|
+
/**
|
|
3
|
+
* What `content_whoami` answers.
|
|
4
|
+
*
|
|
5
|
+
* **Why this is a tool and not only the resource that already exists.** `ebitex-content://whoami`
|
|
6
|
+
* has been served since this server's first release, and many MCP clients surface resources to the
|
|
7
|
+
* *user* and never to the *model*. A resource the agent cannot read is, for this purpose, not an
|
|
8
|
+
* answer: it has no self-service way to ask "where am I scoped?" before interpreting an empty list,
|
|
9
|
+
* which is exactly when it needs to. Both read `session.who`, so the two can never disagree.
|
|
10
|
+
*
|
|
11
|
+
* **Why it costs nothing.** `resolveSession` already called `GET /whoami` at startup to decide which
|
|
12
|
+
* tools to register at all. This renders that same resolution; it issues no request.
|
|
13
|
+
*/
|
|
14
|
+
/** One tool this key cannot see, and the scope that would have shown it. */
|
|
15
|
+
export type WithheldTool = {
|
|
16
|
+
tool: string;
|
|
17
|
+
requires: string;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* The one genuinely new fact this tool reports.
|
|
21
|
+
*
|
|
22
|
+
* Tool *absence* is otherwise indistinguishable from "this server has no such capability" — an agent
|
|
23
|
+
* offered no `content_write` cannot tell a read-scoped key from a server that simply cannot write.
|
|
24
|
+
*
|
|
25
|
+
* The list is **derived** by the caller from the same booleans that gate registration, never
|
|
26
|
+
* enumerated in a table here. A second list of tool→scope is a copy of a fact the `if` blocks already
|
|
27
|
+
* state, and it goes stale the first time a tool moves scope — a failure this codebase has had twice
|
|
28
|
+
* elsewhere, both times in the *reader* rather than the writer.
|
|
29
|
+
*/
|
|
30
|
+
export declare function describeSession(session: Session, withheld: readonly WithheldTool[], serverVersion: string): Record<string, unknown>;
|
|
31
|
+
//# sourceMappingURL=whoami.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"whoami.d.ts","sourceRoot":"","sources":["../../src/tools/whoami.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AAE5C;;;;;;;;;;;GAWG;AAEH,4EAA4E;AAC5E,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;CACjB,CAAA;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,SAAS,YAAY,EAAE,EACjC,aAAa,EAAE,MAAM,GACpB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAuBzB"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The one genuinely new fact this tool reports.
|
|
3
|
+
*
|
|
4
|
+
* Tool *absence* is otherwise indistinguishable from "this server has no such capability" — an agent
|
|
5
|
+
* offered no `content_write` cannot tell a read-scoped key from a server that simply cannot write.
|
|
6
|
+
*
|
|
7
|
+
* The list is **derived** by the caller from the same booleans that gate registration, never
|
|
8
|
+
* enumerated in a table here. A second list of tool→scope is a copy of a fact the `if` blocks already
|
|
9
|
+
* state, and it goes stale the first time a tool moves scope — a failure this codebase has had twice
|
|
10
|
+
* elsewhere, both times in the *reader* rather than the writer.
|
|
11
|
+
*/
|
|
12
|
+
export function describeSession(session, withheld, serverVersion) {
|
|
13
|
+
const { who } = session;
|
|
14
|
+
return {
|
|
15
|
+
organization: { id: who.organizationId, name: who.organizationName, slug: who.organizationSlug },
|
|
16
|
+
environment: { id: who.environmentId, name: who.environmentName },
|
|
17
|
+
actingAs: { roleName: who.roleName, keyName: who.keyName },
|
|
18
|
+
scopes: who.scopes,
|
|
19
|
+
// Reported even though it is not a property of the credential, because a key whose scopes list
|
|
20
|
+
// `authoring` while its write tools are absent is otherwise inexplicable from inside the
|
|
21
|
+
// session — the scope list and the tool list would flatly contradict each other with no visible
|
|
22
|
+
// cause. Hiding the write scopes instead would lie about the credential, which is the one thing
|
|
23
|
+
// this tool exists to tell the truth about.
|
|
24
|
+
readOnlyForced: session.readOnlyRequested,
|
|
25
|
+
serverVersion,
|
|
26
|
+
withheld,
|
|
27
|
+
// The sentence an agent needs *before* it misreads its first empty result. An empty list from
|
|
28
|
+
// this server is always scoped, and saying so is cheaper than the duplicates an agent creates
|
|
29
|
+
// after concluding that nothing exists.
|
|
30
|
+
note: 'This key reads and writes exactly one authoring environment, as one role. An empty result ' +
|
|
31
|
+
'means nothing matched here — not that nothing exists.',
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=whoami.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"whoami.js","sourceRoot":"","sources":["../../src/tools/whoami.ts"],"names":[],"mappings":"AAqBA;;;;;;;;;;GAUG;AACH,MAAM,UAAU,eAAe,CAC7B,OAAgB,EAChB,QAAiC,EACjC,aAAqB;IAErB,MAAM,EAAE,GAAG,EAAE,GAAG,OAAO,CAAA;IAEvB,OAAO;QACL,YAAY,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,cAAc,EAAE,IAAI,EAAE,GAAG,CAAC,gBAAgB,EAAE,IAAI,EAAE,GAAG,CAAC,gBAAgB,EAAE;QAChG,WAAW,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,aAAa,EAAE,IAAI,EAAE,GAAG,CAAC,eAAe,EAAE;QACjE,QAAQ,EAAE,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE;QAC1D,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,+FAA+F;QAC/F,yFAAyF;QACzF,gGAAgG;QAChG,gGAAgG;QAChG,4CAA4C;QAC5C,cAAc,EAAE,OAAO,CAAC,iBAAiB;QACzC,aAAa;QACb,QAAQ;QACR,8FAA8F;QAC9F,8FAA8F;QAC9F,wCAAwC;QACxC,IAAI,EACF,4FAA4F;YAC5F,uDAAuD;KAC1D,CAAA;AACH,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ebitex/content-mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.98",
|
|
4
4
|
"description": "An MCP server for ebitex Content: build and publish a content model from an AI agent.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://developers.ebitex.io/getting-started/content-as-code/",
|