@noodleseed/agent-kit 0.8.1 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -7
- package/manifest.json +57 -17
- package/package.json +1 -1
- package/skills/claude-code/SKILL.md +19 -9
- package/skills/claude-code/references/agent-contract.md +43 -0
- package/skills/claude-code/references/authoring-workflow.md +121 -0
- package/skills/claude-code/references/cli-commands.md +4 -4
- package/skills/claude-code/references/compile-errors.md +1 -1
- package/skills/claude-code/references/deploy-and-ops.md +42 -1
- package/skills/claude-code/references/examples.md +4 -1
- package/skills/claude-code/references/publishing.md +31 -0
- package/skills/claude-code/references/sdk-surface.md +150 -9
- package/skills/claude-code/references/test-in-hosts.md +39 -0
- package/skills/claude-code/references/troubleshooting.md +29 -0
- package/skills/claude-code/references/widgets-and-apps.md +185 -14
- package/skills/codex/SKILL.md +19 -9
- package/skills/codex/references/agent-contract.md +43 -0
- package/skills/codex/references/authoring-workflow.md +121 -0
- package/skills/codex/references/cli-commands.md +4 -4
- package/skills/codex/references/compile-errors.md +1 -1
- package/skills/codex/references/deploy-and-ops.md +42 -1
- package/skills/codex/references/examples.md +4 -1
- package/skills/codex/references/publishing.md +31 -0
- package/skills/codex/references/sdk-surface.md +150 -9
- package/skills/codex/references/test-in-hosts.md +39 -0
- package/skills/codex/references/troubleshooting.md +29 -0
- package/skills/codex/references/widgets-and-apps.md +185 -14
package/README.md
CHANGED
|
@@ -8,9 +8,10 @@ into a project's `.agents/` and `.claude/` skill directories via `noodle agents
|
|
|
8
8
|
|
|
9
9
|
## Contents
|
|
10
10
|
|
|
11
|
-
- `skills/codex/` — the Codex (Codex CLI / AGENTS.md) skill: a `SKILL.md` router plus
|
|
12
|
-
`references/*.md` files (sdk-surface, cli-commands,
|
|
13
|
-
widgets-and-apps, deploy-and-ops,
|
|
11
|
+
- `skills/codex/` — the Codex (Codex CLI / AGENTS.md) skill: a `SKILL.md` router plus eleven
|
|
12
|
+
`references/*.md` files (sdk-surface, cli-commands, agent-contract, compile-errors,
|
|
13
|
+
authoring-workflow, widgets-and-apps, test-in-hosts, troubleshooting, deploy-and-ops, publishing,
|
|
14
|
+
examples).
|
|
14
15
|
- `skills/claude-code/` — the Claude Code skill, same hierarchical tree.
|
|
15
16
|
- `manifest.json` — `{ packageVersion, files: [{ path, sha256, agentTarget }] }`. The CLI verifies every
|
|
16
17
|
file's sha256 against this manifest before writing it into a user's project; a mismatch refuses the
|
|
@@ -26,12 +27,13 @@ Skills updated in vX — run `noodle agents setup --write` to refresh.
|
|
|
26
27
|
```
|
|
27
28
|
|
|
28
29
|
`noodle agents setup --write` then fetches this package, sha256-verifies it against the manifest, and
|
|
29
|
-
writes the fresh
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
writes the fresh skill tree into the project (the managed `AGENTS.md`/`CLAUDE.md` block stays bundled,
|
|
31
|
+
since it is project-specific). Offline or on verification failure it falls back to the bundled snapshot.
|
|
32
|
+
Run `noodle agents doctor` to see installed vs registry skill versions and detect local edits to bundled
|
|
33
|
+
reference files.
|
|
32
34
|
|
|
33
35
|
## License
|
|
34
36
|
|
|
35
37
|
Apache-2.0. This package is generated and published from the
|
|
36
38
|
[`noodle-borg`](https://github.com/NoodleSeed-com/noodle-borg) repository; the renderer is the private
|
|
37
|
-
`@noodle-borg/agent-kit` workspace package.
|
|
39
|
+
`@noodle-borg/agent-kit` workspace package.
|
package/manifest.json
CHANGED
|
@@ -1,84 +1,124 @@
|
|
|
1
1
|
{
|
|
2
|
-
"packageVersion": "0.
|
|
2
|
+
"packageVersion": "0.10.0",
|
|
3
3
|
"files": [
|
|
4
4
|
{
|
|
5
5
|
"path": "skills/codex/SKILL.md",
|
|
6
|
-
"sha256": "
|
|
6
|
+
"sha256": "9b4a0f08e67add37749096b5cb496d29407637d9602d0f3015f1362dff2a29f7",
|
|
7
7
|
"agentTarget": "codex"
|
|
8
8
|
},
|
|
9
9
|
{
|
|
10
10
|
"path": "skills/codex/references/sdk-surface.md",
|
|
11
|
-
"sha256": "
|
|
11
|
+
"sha256": "d5da0c1ec33aa8d2770e145293174e99cff0c73264756dafe121e818ade14abf",
|
|
12
12
|
"agentTarget": "codex"
|
|
13
13
|
},
|
|
14
14
|
{
|
|
15
15
|
"path": "skills/codex/references/cli-commands.md",
|
|
16
|
-
"sha256": "
|
|
16
|
+
"sha256": "c50bf5ec6f43bd9fb7115ea9c9eb8de33c93e123f3e2d396785fe75ba094d40d",
|
|
17
|
+
"agentTarget": "codex"
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"path": "skills/codex/references/agent-contract.md",
|
|
21
|
+
"sha256": "8e884a90f7c155a9f1d3773c7c037f88a98ac8d5c5d23e8100349ae82d068e6d",
|
|
17
22
|
"agentTarget": "codex"
|
|
18
23
|
},
|
|
19
24
|
{
|
|
20
25
|
"path": "skills/codex/references/compile-errors.md",
|
|
21
|
-
"sha256": "
|
|
26
|
+
"sha256": "22692f2fda9c7d8ef0aa54e58148d22cf740bf722ceb79a942f6f146009a6bda",
|
|
22
27
|
"agentTarget": "codex"
|
|
23
28
|
},
|
|
24
29
|
{
|
|
25
30
|
"path": "skills/codex/references/authoring-workflow.md",
|
|
26
|
-
"sha256": "
|
|
31
|
+
"sha256": "ad5866ad739885592eb729fdd0bf18d602b886021309e28565a090d66f7c2e9a",
|
|
27
32
|
"agentTarget": "codex"
|
|
28
33
|
},
|
|
29
34
|
{
|
|
30
35
|
"path": "skills/codex/references/widgets-and-apps.md",
|
|
31
|
-
"sha256": "
|
|
36
|
+
"sha256": "46ee39731565bf6bbf2b818125685b64599011bcd825b4c279f1232ecebd5839",
|
|
37
|
+
"agentTarget": "codex"
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"path": "skills/codex/references/test-in-hosts.md",
|
|
41
|
+
"sha256": "08e44784a0d838c322d443eae6b35d5c75b4252a0975db835ef504535e25584a",
|
|
42
|
+
"agentTarget": "codex"
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"path": "skills/codex/references/troubleshooting.md",
|
|
46
|
+
"sha256": "4e0446d67d4ab037ecb6c9ffdf28494b42ed410f5c94ad7c498c3545f746eefb",
|
|
32
47
|
"agentTarget": "codex"
|
|
33
48
|
},
|
|
34
49
|
{
|
|
35
50
|
"path": "skills/codex/references/deploy-and-ops.md",
|
|
36
|
-
"sha256": "
|
|
51
|
+
"sha256": "0175101939ca5ea6823a18ce83a32311f5d9937ef8469a431dd0576ad0997fe4",
|
|
52
|
+
"agentTarget": "codex"
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
"path": "skills/codex/references/publishing.md",
|
|
56
|
+
"sha256": "fb0be4c9c9bc9fd68f4e7ed8e9b7e4c8677c415130d441c28590ba0df6cb5aae",
|
|
37
57
|
"agentTarget": "codex"
|
|
38
58
|
},
|
|
39
59
|
{
|
|
40
60
|
"path": "skills/codex/references/examples.md",
|
|
41
|
-
"sha256": "
|
|
61
|
+
"sha256": "9f3ce479669040f0c58c9876b2bbca90821c69a760d0b020a56072bd6e549d73",
|
|
42
62
|
"agentTarget": "codex"
|
|
43
63
|
},
|
|
44
64
|
{
|
|
45
65
|
"path": "skills/claude-code/SKILL.md",
|
|
46
|
-
"sha256": "
|
|
66
|
+
"sha256": "8b900dc831b5dde27f3b1859041b688ec0b04be940e8748e2329a5e92014abd2",
|
|
47
67
|
"agentTarget": "claude-code"
|
|
48
68
|
},
|
|
49
69
|
{
|
|
50
70
|
"path": "skills/claude-code/references/sdk-surface.md",
|
|
51
|
-
"sha256": "
|
|
71
|
+
"sha256": "d5da0c1ec33aa8d2770e145293174e99cff0c73264756dafe121e818ade14abf",
|
|
52
72
|
"agentTarget": "claude-code"
|
|
53
73
|
},
|
|
54
74
|
{
|
|
55
75
|
"path": "skills/claude-code/references/cli-commands.md",
|
|
56
|
-
"sha256": "
|
|
76
|
+
"sha256": "c50bf5ec6f43bd9fb7115ea9c9eb8de33c93e123f3e2d396785fe75ba094d40d",
|
|
77
|
+
"agentTarget": "claude-code"
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
"path": "skills/claude-code/references/agent-contract.md",
|
|
81
|
+
"sha256": "8e884a90f7c155a9f1d3773c7c037f88a98ac8d5c5d23e8100349ae82d068e6d",
|
|
57
82
|
"agentTarget": "claude-code"
|
|
58
83
|
},
|
|
59
84
|
{
|
|
60
85
|
"path": "skills/claude-code/references/compile-errors.md",
|
|
61
|
-
"sha256": "
|
|
86
|
+
"sha256": "22692f2fda9c7d8ef0aa54e58148d22cf740bf722ceb79a942f6f146009a6bda",
|
|
62
87
|
"agentTarget": "claude-code"
|
|
63
88
|
},
|
|
64
89
|
{
|
|
65
90
|
"path": "skills/claude-code/references/authoring-workflow.md",
|
|
66
|
-
"sha256": "
|
|
91
|
+
"sha256": "ad5866ad739885592eb729fdd0bf18d602b886021309e28565a090d66f7c2e9a",
|
|
67
92
|
"agentTarget": "claude-code"
|
|
68
93
|
},
|
|
69
94
|
{
|
|
70
95
|
"path": "skills/claude-code/references/widgets-and-apps.md",
|
|
71
|
-
"sha256": "
|
|
96
|
+
"sha256": "46ee39731565bf6bbf2b818125685b64599011bcd825b4c279f1232ecebd5839",
|
|
97
|
+
"agentTarget": "claude-code"
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
"path": "skills/claude-code/references/test-in-hosts.md",
|
|
101
|
+
"sha256": "08e44784a0d838c322d443eae6b35d5c75b4252a0975db835ef504535e25584a",
|
|
102
|
+
"agentTarget": "claude-code"
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
"path": "skills/claude-code/references/troubleshooting.md",
|
|
106
|
+
"sha256": "4e0446d67d4ab037ecb6c9ffdf28494b42ed410f5c94ad7c498c3545f746eefb",
|
|
72
107
|
"agentTarget": "claude-code"
|
|
73
108
|
},
|
|
74
109
|
{
|
|
75
110
|
"path": "skills/claude-code/references/deploy-and-ops.md",
|
|
76
|
-
"sha256": "
|
|
111
|
+
"sha256": "0175101939ca5ea6823a18ce83a32311f5d9937ef8469a431dd0576ad0997fe4",
|
|
112
|
+
"agentTarget": "claude-code"
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
"path": "skills/claude-code/references/publishing.md",
|
|
116
|
+
"sha256": "fb0be4c9c9bc9fd68f4e7ed8e9b7e4c8677c415130d441c28590ba0df6cb5aae",
|
|
77
117
|
"agentTarget": "claude-code"
|
|
78
118
|
},
|
|
79
119
|
{
|
|
80
120
|
"path": "skills/claude-code/references/examples.md",
|
|
81
|
-
"sha256": "
|
|
121
|
+
"sha256": "9f3ce479669040f0c58c9876b2bbca90821c69a760d0b020a56072bd6e549d73",
|
|
82
122
|
"agentTarget": "claude-code"
|
|
83
123
|
}
|
|
84
124
|
]
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@noodleseed/agent-kit",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Self-checking, self-updating agent skills for the Noodle Seed CLI. Authored in this repo by @noodle-borg/agent-kit; this is the published, independently-versioned canonical skills artifact the CLI fetches and verifies.",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: noodle-seed
|
|
3
3
|
description: Use when building, validating, testing, deploying, or operating a local or hosted Noodle Seed MCP server or app authored in TypeScript with the noodle CLI.
|
|
4
|
-
version: 0.
|
|
5
|
-
hash:
|
|
4
|
+
version: 0.10.0
|
|
5
|
+
hash: 5aa15e5bf381543c
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# Noodle Seed
|
|
@@ -13,22 +13,32 @@ Use this skill for project-local Noodle Seed authoring in Claude Code; preserve
|
|
|
13
13
|
|
|
14
14
|
## Golden path
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
16
|
+
This CLI is agent-native: the cold-agent-path commands speak the `--json` envelope (hosted admin/ops commands are still being normalized). Drive the loop by parsing machine state, not human prose. The full envelope, exit codes, and output modes are in `references/agent-contract.md`.
|
|
17
|
+
|
|
18
|
+
1. **Discover** — `noodle commands --json`: every command, subcommand, flag, and exit code (don't read source).
|
|
19
|
+
2. **Author** — edit `src/server.ts` (the configured entrypoint); follow the capability recipe in `references/sdk-surface.md` and `references/examples.md`.
|
|
20
|
+
3. **Validate** — `noodle validate --json`; on failure `{ok:false,error:{code,message,fix,next,errors:[{code,path,message}]}}` — the per-field detail is in `error.errors[]`.
|
|
21
|
+
4. **Repair** — fix each `error.errors[]` entry at its `path`, then re-run `noodle validate --json`; `noodle validate --fix-prompt` emits ready-to-apply repair prose. Never freeform re-edit (see `references/compile-errors.md`).
|
|
22
|
+
5. **Smoke** — `noodle test --json`: local compile plus a loopback MCP smoke.
|
|
23
|
+
6. **Apps/widgets** — `noodle check --json` (add `--target chatgpt|claude`), then `noodle devtools` (see `references/widgets-and-apps.md`).
|
|
24
|
+
7. **Deploy** — `noodle deploy`; auth fails clean with `error.next` = `noodle login` (see `references/deploy-and-ops.md`).
|
|
25
|
+
8. **Wire into a host** — `noodle connect <codex|claude-code|chatgpt>` (prove it in a real host per `references/test-in-hosts.md`; debug symptoms with `references/troubleshooting.md`).
|
|
26
|
+
9. **Health** — `noodle metrics --agent-output`: a health verdict plus the exact next command per attention item.
|
|
21
27
|
|
|
22
28
|
## References
|
|
23
29
|
|
|
24
30
|
Load these on demand:
|
|
25
31
|
|
|
32
|
+
- `references/agent-contract.md` — the `--json` envelope, exit codes, and the three output modes.
|
|
26
33
|
- `references/sdk-surface.md` — what to import from `@noodleseed/one` and which builder to use.
|
|
27
34
|
- `references/cli-commands.md` — every `noodle` command, grouped by area.
|
|
28
35
|
- `references/compile-errors.md` — fix `noodle validate` errors by code.
|
|
29
|
-
- `references/authoring-workflow.md` — input paths (scrape / OpenAPI import / user interview), the validate→test→dev repair loop, connectors, and secrets/variables.
|
|
30
|
-
- `references/widgets-and-apps.md` — MCP Apps, React `view` widgets, and CSP.
|
|
36
|
+
- `references/authoring-workflow.md` — input paths (scrape / OpenAPI import / user interview), the fit check, the validate→test→dev repair loop, connectors, and secrets/variables.
|
|
37
|
+
- `references/widgets-and-apps.md` — MCP Apps, React `view` widgets, the widget hook surface, output shaping, and CSP.
|
|
38
|
+
- `references/test-in-hosts.md` — connect and test in ChatGPT (developer mode), Claude, agent hosts, and MCP Inspector.
|
|
39
|
+
- `references/troubleshooting.md` — runtime symptom → cause → fix, in-host and hosted.
|
|
31
40
|
- `references/deploy-and-ops.md` — login/link/deploy/status/access and hosted operations.
|
|
41
|
+
- `references/publishing.md` — submit to the ChatGPT apps directory and Claude connectors directory.
|
|
32
42
|
- `references/examples.md` — flagship example index and a canonical `server.ts`.
|
|
33
43
|
|
|
34
44
|
## Safety
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Agent contract: --json, exit codes, output modes
|
|
2
|
+
|
|
3
|
+
The cold-agent-path commands (`init`, `validate`, `test`, `check`, `tools`/`resources`/`prompts`, `deploy`, `metrics`, `events`, `agents`) are agent-native and return the envelope below; hosted admin/ops commands (`status`, `inspect`, `smoke`, `logs`, `update`) are still being normalized. Decide what to do next by parsing machine state — do not scrape human prose.
|
|
4
|
+
|
|
5
|
+
## Contents
|
|
6
|
+
|
|
7
|
+
- Response envelope
|
|
8
|
+
- Exit codes
|
|
9
|
+
- Output modes
|
|
10
|
+
- Repair loop
|
|
11
|
+
|
|
12
|
+
## Response envelope
|
|
13
|
+
|
|
14
|
+
A `--json` command returns exactly one JSON object:
|
|
15
|
+
|
|
16
|
+
- **Success**: `{ ok: true, data, warnings? }` — `data` is the command payload; `warnings?` is an optional array of non-fatal notes.
|
|
17
|
+
- **Failure**: `{ ok: false, error: { code, message, cause?, fix, next, requestId? } }` — `code` is the stable machine code to branch on, `message` is human text, `cause?` is the underlying error, `fix` states the correction, `next` names the command to run next, `requestId?` correlates a hosted call.
|
|
18
|
+
- **Field errors** carry a dotted `path`: multi-error commands (e.g. `noodle validate`) nest them under `error.errors[]`, each `{ code, path, message }`. The top-level `error` still carries `code`/`message`/`fix`/`next`; the per-field `path`s live in `error.errors[]`.
|
|
19
|
+
- **Repair prose is isolated**: ready-to-apply repair text appears only under `error.fixPrompt` (surfaced by `--fix-prompt`), never mixed into `message` or `data`.
|
|
20
|
+
|
|
21
|
+
## Exit codes
|
|
22
|
+
|
|
23
|
+
Branch on the process exit code before parsing the body:
|
|
24
|
+
|
|
25
|
+
| Code | Meaning |
|
|
26
|
+
| :-- | :-- |
|
|
27
|
+
| `0` | ok |
|
|
28
|
+
| `1` | failure (command ran, the work failed) |
|
|
29
|
+
| `2` | usage (bad flags or arguments) |
|
|
30
|
+
| `3` | auth (login or permission required) |
|
|
31
|
+
| `4` | unreachable (service or network) |
|
|
32
|
+
| `5` | mcp/tool-call error (a `tools`/`resources`/`prompts`/`test` smoke call failed) |
|
|
33
|
+
|
|
34
|
+
## Output modes
|
|
35
|
+
|
|
36
|
+
Two kinds of output — never mix them:
|
|
37
|
+
|
|
38
|
+
- `--json` — **machine state**: the envelope above. Use it to decide what to do next.
|
|
39
|
+
- `--fix-prompt` / `--agent-output` (aliases) — **agent-readable text**, not the envelope: a ready-to-apply repair prompt for authoring commands (`validate`/`test`/`check`), or an operational `health` verdict (`ok`/`attention`) with `attention[]` next-commands for ops commands (`metrics`/`doctor`/`alerts`). Use it to author a fix or judge a running deployment.
|
|
40
|
+
|
|
41
|
+
## Repair loop
|
|
42
|
+
|
|
43
|
+
On a `validate` failure: parse `error.code` + `path`, fix exactly that field in `src/server.ts`, then re-run `noodle validate --json`. Never freeform re-edit. Repeat until `ok: true`, then `noodle test --json`.
|
|
@@ -3,8 +3,13 @@
|
|
|
3
3
|
## Contents
|
|
4
4
|
|
|
5
5
|
- Input paths
|
|
6
|
+
- Fit check
|
|
6
7
|
- Repair loop
|
|
7
8
|
- Connectors
|
|
9
|
+
- HTTP connector example
|
|
10
|
+
- Worked example (full server)
|
|
11
|
+
- Compute connector example
|
|
12
|
+
- Tests
|
|
8
13
|
- Secrets and variables
|
|
9
14
|
- Boundaries
|
|
10
15
|
|
|
@@ -14,6 +19,10 @@
|
|
|
14
19
|
2. **OpenAPI import** — `noodle import openapi <file>` emits a starter `server.ts` from a spec. Use it when the user provides an OpenAPI document.
|
|
15
20
|
3. **User interview** — Noodle does not interview; you do. Cover custom APIs/integrations, eligibility rules, quoting/approval logic, and private schemas (SQL DDL or JSON samples for custom `connector` declarations). Ask for concrete examples and sample payloads; do not guess a schema from a URL or invent endpoints.
|
|
16
21
|
|
|
22
|
+
## Fit check
|
|
23
|
+
|
|
24
|
+
Before building, confirm the idea fits a conversational surface: 1–3 focused actions where saying it beats clicking, plus data or actions the model lacks on its own. Poor fits — long-form or static content, dashboards, deep multi-step navigation, or a full app port. When an idea does not fit, narrow the scope to the actions that do.
|
|
25
|
+
|
|
17
26
|
## Repair loop
|
|
18
27
|
|
|
19
28
|
Author in `server.ts`, then `noodle validate` → fix cited errors (see `compile-errors.md`) → re-validate → `noodle test` → `noodle dev`. Keep the loop tight and error-driven.
|
|
@@ -27,6 +36,118 @@ Declare connectors as data, not imperative code:
|
|
|
27
36
|
|
|
28
37
|
Tools record connector calls into a flow; recording is not execution. Do not branch on runtime outputs with native `if` — use declarative `when(...)` conditions.
|
|
29
38
|
|
|
39
|
+
HTTP connector auth variants: `bearer` (`{ kind: "bearer", secret: secret("API_TOKEN") }`), `apiKey` (`{ kind: "apiKey", header: "X-API-Key", secret: secret("API_KEY") }`), `oauth2ClientCredentials`, `delegatedOAuth`, and `delegatedSessionCookie`. Use managed `secret(...)` / `variable(...)` refs for all values that differ by org/app/env.
|
|
40
|
+
|
|
41
|
+
## HTTP connector example
|
|
42
|
+
|
|
43
|
+
The operation mapping in detail: `request` templates the outbound call, `response` maps the HTTP body into your typed `output`.
|
|
44
|
+
|
|
45
|
+
```ts
|
|
46
|
+
import { connector, secret, variable } from '@noodleseed/one';
|
|
47
|
+
|
|
48
|
+
const crm = connector('crm').version('1.0.0').http({
|
|
49
|
+
baseUrl: variable('CRM_BASE_URL'),
|
|
50
|
+
allowedOrigins: [variable('CRM_BASE_URL')],
|
|
51
|
+
auth: { kind: 'bearer', secret: secret('CRM_TOKEN') },
|
|
52
|
+
operations: {
|
|
53
|
+
findCustomer: {
|
|
54
|
+
type: 'read',
|
|
55
|
+
input: { email: { type: "string", required: true } },
|
|
56
|
+
output: { id: { type: "string", required: true }, name: { type: "string" } },
|
|
57
|
+
method: "GET",
|
|
58
|
+
path: "/customers",
|
|
59
|
+
request: { query: { email: "${args.email}" } },
|
|
60
|
+
response: { id: "${response.body.data.0.id}", name: "${response.body.data.0.name}" },
|
|
61
|
+
},
|
|
62
|
+
createTicket: {
|
|
63
|
+
type: 'action',
|
|
64
|
+
input: { customerId: { type: "string", required: true }, body: { type: "string", required: true } },
|
|
65
|
+
output: { ticketId: { type: "string", required: true } },
|
|
66
|
+
method: "POST",
|
|
67
|
+
path: "/tickets",
|
|
68
|
+
request: { body: { customer_id: "${args.customerId}", body: "${args.body}" } },
|
|
69
|
+
response: { ticketId: "${response.body.id}" },
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
});
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Use `${args.field}` for tool/operation inputs and `${response.body.path}` for response mapping. Prefer explicit `allowedOrigins`; OAuth token/session URLs must also be on an allowed origin. For client credentials use `{ kind: "oauth2ClientCredentials", tokenUrl, clientId, clientSecret, scopes? }`; for per-customer downstream calls use `delegatedOAuth` or `delegatedSessionCookie` with a matching `customerAuth` server option.
|
|
76
|
+
|
|
77
|
+
## Worked example (full server)
|
|
78
|
+
|
|
79
|
+
Declare the API as data, bind it with `use`, then record a call in a tool. `auth` reads a managed `secret(...)` — never inline a key. Map the HTTP body into your typed `output` with `${response...}`.
|
|
80
|
+
|
|
81
|
+
```ts
|
|
82
|
+
import { connector, secret, server, tool, z } from '@noodleseed/one';
|
|
83
|
+
|
|
84
|
+
const crm = connector('acme_crm')
|
|
85
|
+
.version('1.0.0')
|
|
86
|
+
.http({
|
|
87
|
+
baseUrl: 'https://api.acme.example',
|
|
88
|
+
allowedOrigins: ['https://api.acme.example'],
|
|
89
|
+
auth: { kind: 'apiKey', header: 'X-Api-Key', secret: secret('ACME_CRM_TOKEN') },
|
|
90
|
+
operations: {
|
|
91
|
+
get_ticket: {
|
|
92
|
+
type: 'read',
|
|
93
|
+
method: 'GET',
|
|
94
|
+
path: '/v1/tickets/{id}',
|
|
95
|
+
input: { id: { type: 'string', required: true } },
|
|
96
|
+
output: { subject: { type: 'string' }, status: { type: 'string' } },
|
|
97
|
+
response: { subject: '${response.data.subject}', status: '${response.data.state}' },
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
export default server('support', { title: 'Support', version: '1.0.0', use: { crm } }, [
|
|
103
|
+
tool('ticket_status', {
|
|
104
|
+
description: 'Look up a support ticket by id.',
|
|
105
|
+
input: z.object({ ticket_id: z.string() }),
|
|
106
|
+
output: z.object({ subject: z.string(), status: z.string() }),
|
|
107
|
+
fulfil: ({ input, connectors }) => {
|
|
108
|
+
const ticket = connectors.crm.get_ticket({ id: input.ticket_id });
|
|
109
|
+
return { subject: ticket.subject, status: ticket.status };
|
|
110
|
+
},
|
|
111
|
+
}),
|
|
112
|
+
]);
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
More: `auth.kind` is `bearer` | `apiKey` (needs `header`) | `oauth2ClientCredentials` | `delegatedOAuth` | `delegatedSessionCookie`. Use `.compute(name, { input, output, run })` for a sandboxed transform; `provides:` (instead of `use:`) exposes a connector only to compute `callOperation`; and `noodle import openapi <file>` generates a connector from an OpenAPI spec.
|
|
116
|
+
|
|
117
|
+
## Compute connector example
|
|
118
|
+
|
|
119
|
+
```ts
|
|
120
|
+
const scoring = connector('scoring').version('1.0.0').compute('normalize', {
|
|
121
|
+
input: { email: { type: "string", required: true }, priority: { type: "string" } },
|
|
122
|
+
output: { score: { type: "number", required: true } },
|
|
123
|
+
calls: { findCustomer: 'crm.findCustomer' },
|
|
124
|
+
limits: { timeoutMs: 1000, maxHostCalls: 2 },
|
|
125
|
+
run(input, { callOperation }) {
|
|
126
|
+
const customer = callOperation("findCustomer", { email: input.email }) as { id?: string };
|
|
127
|
+
return { score: customer.id && input.priority === "high" ? 100 : 50 };
|
|
128
|
+
},
|
|
129
|
+
});
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Compute `run` functions are serialized and sandboxed: no imports, no closure capture, no `fetch`, no `process`. Any backing-system call must be declared in `calls` and invoked through `callOperation`. For conditional flow edges, use `when(...)` in recorded fulfilment instead of native branching on connector outputs.
|
|
133
|
+
|
|
134
|
+
## Tests
|
|
135
|
+
|
|
136
|
+
Use Vitest for app-local tests. Keep fixtures project-local; do not import from `examples/`. A minimum test suite imports the default server, checks the intended definitions compile, then lets `noodle test --json` perform the loopback MCP smoke.
|
|
137
|
+
|
|
138
|
+
```ts
|
|
139
|
+
import { describe, expect, it } from 'vitest';
|
|
140
|
+
import app from '../src/server.js';
|
|
141
|
+
|
|
142
|
+
describe('server', () => {
|
|
143
|
+
it('declares the expected tool surface', () => {
|
|
144
|
+
expect(app.name).toBe('support_assistant');
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
After focused tests pass, run `noodle validate --json`, `noodle test --json`, and then `noodle dev` for interactive local verification.
|
|
150
|
+
|
|
30
151
|
## Secrets and variables
|
|
31
152
|
|
|
32
153
|
Author managed config as `secret("NAME")` / `variable("NAME")` and operate it with `noodle secrets set` / `noodle variables set` (scoped org/app/env). Never inline secret values in `server.ts`, tests, or generated files.
|
|
@@ -54,7 +54,7 @@ Every `noodle` command, grouped by area. Local authoring commands (`validate`, `
|
|
|
54
54
|
| `noodle rollback` | Roll back to a previous deployment. |
|
|
55
55
|
| `noodle archive` | Archive the whole app: endpoints answer 410 Gone; hard-deleted after the retention window. |
|
|
56
56
|
| `noodle restore` | Restore an archived app within the retention window. |
|
|
57
|
-
| `noodle access` | Set the access mode (owner-only
|
|
57
|
+
| `noodle access` | Set the access mode (owner-only\|org-members\|authenticated\|customers). |
|
|
58
58
|
| `noodle apps` | List or inspect hosted apps for an org (`apps list`/`apps inspect <app>`). |
|
|
59
59
|
| `noodle envs` | List or inspect environments for an app (`envs list`/`envs inspect <env>`). |
|
|
60
60
|
| `noodle deployments` | List or inspect individual deployments (`deployments list`/`deployments inspect <id>`). |
|
|
@@ -64,7 +64,7 @@ Every `noodle` command, grouped by area. Local authoring commands (`validate`, `
|
|
|
64
64
|
| `noodle whoami` | Print the current authenticated user. |
|
|
65
65
|
| `noodle list` | Removed — promoted to `deployments list` (prints the recovery pointer and exits 2). |
|
|
66
66
|
| `noodle github` | Connect, inspect, or disconnect the GitHub repository behind an app’s GitHub-native deploys (`connect`/`status`/`disconnect`; `connect` opens a browser install, `--repo` for headless). |
|
|
67
|
-
| `noodle target` | Show or set the deployment target (local
|
|
67
|
+
| `noodle target` | Show or set the deployment target (local\|cloud\|other). |
|
|
68
68
|
|
|
69
69
|
## Org & members
|
|
70
70
|
|
|
@@ -87,8 +87,8 @@ Every `noodle` command, grouped by area. Local authoring commands (`validate`, `
|
|
|
87
87
|
| `noodle audit` | Operator governance audit status and event queries. |
|
|
88
88
|
| `noodle logs` | View service/deployment logs. |
|
|
89
89
|
| `noodle metrics` | MCP analytics for a deployed server (volume, sessions, latency percentiles, two-tier errors, tools, clients). Agents: `noodle metrics --agent-output` for a health verdict + next actions. |
|
|
90
|
-
| `noodle events` | The per-request MCP event stream with status/tool/client filters; `--session <id>` replays one session in order. Agents: add `--json` and filter (`--status tool_error
|
|
91
|
-
| `noodle alerts` | Analytics alert rules (`add
|
|
90
|
+
| `noodle events` | The per-request MCP event stream with status/tool/client filters; `--session <id>` replays one session in order. Agents: add `--json` and filter (`--status tool_error\|mcp_error`) when debugging. |
|
|
91
|
+
| `noodle alerts` | Analytics alert rules (`add\|list\|remove\|test`): an edge-triggered webhook fires when error share, error count, calls, or p95 latency breaches. Webhook URLs are stored server-side and shown redacted. |
|
|
92
92
|
| `noodle policy` | Manage policy (status/list/show/effective/simulate/suspend/quota/rate/...). |
|
|
93
93
|
|
|
94
94
|
## CLI maintenance
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
## The repair loop
|
|
9
9
|
|
|
10
|
-
Run `noodle validate` (add `--json` for machine-readable
|
|
10
|
+
Run `noodle validate` (add `--json` for the machine-readable envelope, `--fix-prompt` for an agent repair prompt). On failure the envelope is `{ok:false,error:{code,message,fix,next,errors:[{code,path,message}]}}`: each entry in `error.errors[]` carries a `code`, a dotted `path` to the offending field, and a `message`; many also carry `expected`/`got`, `didYouMean`/`suggestions`, and a `docAnchor` (the full envelope is in `agent-contract.md`). Fix the specific error the `path` locates, then re-validate. Do not freeform re-edit. Once `noodle validate` passes, run `noodle test`, then `noodle dev`.
|
|
11
11
|
|
|
12
12
|
## Error codes
|
|
13
13
|
|
|
@@ -5,9 +5,12 @@
|
|
|
5
5
|
- Authenticate
|
|
6
6
|
- Link and target
|
|
7
7
|
- Deploy and inspect
|
|
8
|
+
- Connect into a host
|
|
8
9
|
- Access modes
|
|
9
10
|
- Org and members
|
|
10
11
|
- Config and observability
|
|
12
|
+
- Agent-safe CLI recipes
|
|
13
|
+
- Analytics
|
|
11
14
|
|
|
12
15
|
## Authenticate
|
|
13
16
|
|
|
@@ -21,6 +24,24 @@
|
|
|
21
24
|
|
|
22
25
|
`noodle deploy` deploys the server. Then `noodle open` (latest URL), `noodle status`, `noodle inspect` (metadata, no secrets), `noodle smoke` (readiness diagnostics), and `noodle rollback <deploymentId>` to revert.
|
|
23
26
|
|
|
27
|
+
## Connect into a host
|
|
28
|
+
|
|
29
|
+
Once deployed, register the server as a tool in a host with `noodle connect <host>` (`claude-code`, `codex`, `chatgpt`, `cursor`, `vscode`, `claude`, `inspector`) — it prints the exact config to paste.
|
|
30
|
+
|
|
31
|
+
- **Claude Code / Claude Desktop** (verified) — add the `mcpServers` block, or one-shot `claude mcp add-json noodle-server '<json>'`:
|
|
32
|
+
|
|
33
|
+
```json
|
|
34
|
+
{
|
|
35
|
+
"mcpServers": {
|
|
36
|
+
"noodle-server": { "type": "https", "url": "https://<app>.mcp.noodleseed.dev" }
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
- **Codex / Cursor / VS Code** — the same `mcpServers` block is emitted as a starting point (these hosts' config formats are not officially documented). Wiring a deployed Noodle server into Codex means registering that block in Codex's MCP config.
|
|
42
|
+
- **ChatGPT / Claude.ai** — no config file: open the host's Settings → Connectors → Add custom connector, paste the MCP URL, then authenticate.
|
|
43
|
+
- `noodle connect codex|claude-code --write` writes the project-local agent files (only these two targets).
|
|
44
|
+
|
|
24
45
|
## Access modes
|
|
25
46
|
|
|
26
47
|
`noodle access set owner-only|org-members|authenticated|customers` controls who can call the deployed server. Hosted access is identity-based; never add static data-plane keys.
|
|
@@ -33,6 +54,26 @@
|
|
|
33
54
|
|
|
34
55
|
Manage runtime config with `noodle secrets` / `noodle variables` (scoped org/app/env). Operators use `noodle logs`, `noodle audit`, and `noodle policy` for logs, governance audit, and policy.
|
|
35
56
|
|
|
57
|
+
## Agent-safe CLI recipes
|
|
58
|
+
|
|
59
|
+
Use explicit flags in headless runs so commands never wait for a prompt:
|
|
60
|
+
|
|
61
|
+
```sh
|
|
62
|
+
noodle link --org acme --app support-assistant --env prod
|
|
63
|
+
noodle secrets set CRM_TOKEN --scope env --org acme --app support-assistant --env prod --from-env CRM_TOKEN
|
|
64
|
+
noodle secrets set CRM_CERT --scope env --org acme --app support-assistant --env prod --from-file ./cert.pem
|
|
65
|
+
printf %s "$CRM_TOKEN" | noodle secrets set CRM_TOKEN --scope env --org acme --app support-assistant --env prod --from-stdin
|
|
66
|
+
noodle variables set CRM_BASE_URL --scope env --org acme --app support-assistant --env prod --value https://crm.example.com
|
|
67
|
+
noodle secrets list --scope env --org acme --app support-assistant --env prod --json
|
|
68
|
+
noodle validate --json
|
|
69
|
+
noodle test --json
|
|
70
|
+
noodle deploy --json
|
|
71
|
+
noodle smoke --json
|
|
72
|
+
noodle agents doctor --json
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
`secrets resolve` is for local diagnostics only; do not print resolved values into prompts, logs, tests, or docs. Prefer `--from-env`, `--from-file`, or `--from-stdin` over inline `--value` for sensitive values. Variables may use `--value` when the value is non-secret.
|
|
76
|
+
|
|
36
77
|
## Analytics (verify after deploy, debug errors)
|
|
37
78
|
|
|
38
|
-
After a deploy gets traffic, verify with `noodle metrics --agent-output` — it returns a `health` verdict (`ok`/`attention`), a one-line summary, and `attention[]` items each carrying the exact next command. When a tool errors, drill in with `noodle events --tool <name> --json` (filters: `--status tool_error|mcp_error`, `--client <name>`); `noodle events --session <id> --json` replays one session chronologically. `--json` on both returns the full payload; human runs get the branded report. Two-tier errors: `tool_error` is recoverable (handed back to the model), `mcp_error` needs attention (protocol/timeout/internal).
|
|
79
|
+
After a deploy gets traffic, verify with `noodle metrics --agent-output` — it returns a `health` verdict (`ok`/`attention`), a one-line summary, and `attention[]` items each carrying the exact next command. When a tool errors, drill in with `noodle events --tool <name> --json` (filters: `--status tool_error|mcp_error`, `--client <name>`); `noodle events --session <id> --json` replays one session chronologically. `--json` on both returns the full payload; human runs get the branded report. Two-tier errors: `tool_error` is recoverable (handed back to the model), `mcp_error` needs attention (protocol/timeout/internal). Wire edge-triggered webhooks on error share, error count, calls, or p95 latency with `noodle alerts add|list|remove|test`.
|
|
@@ -6,11 +6,14 @@ Flagship examples (one per capability). Read the matching example for the patter
|
|
|
6
6
|
| :-- | :-- |
|
|
7
7
|
| `hello` | Minimal TypeScript quickstart — a single tool, no connectors/widgets. |
|
|
8
8
|
| `weather` | HTTP connectors, multi-step flows, and the sandboxed compute connector. |
|
|
9
|
-
| `
|
|
9
|
+
| `food-ordering` | Consumer ordering MCP App widgets, app-only helpers, cart state, assets, branding, and handoff. |
|
|
10
10
|
| `customer-auth` | End-user (customer) auth via OIDC/Firebase bridge with delegated credentials. |
|
|
11
11
|
| `stateful-draft` | Durable, caller-scoped widget state handles with optimistic revisions. |
|
|
12
12
|
| `perplexity` | A real SaaS API with bearer auth and a managed `secret`. |
|
|
13
|
+
| `bitcoin` | API-key HTTP connector, custom auth header, and compute normalization. |
|
|
14
|
+
| `sharepoint` | Microsoft SharePoint delegated Microsoft Entra auth and Graph tools. |
|
|
13
15
|
| `internal-ops-demo` | Governed internal connectivity — tools/resources/prompts, role-shaped output. |
|
|
16
|
+
| `docs-assistant` | Docs/knowledge assistant grounding coding agents in the live docs export. |
|
|
14
17
|
|
|
15
18
|
## Canonical server.ts
|
|
16
19
|
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Publish to app directories
|
|
2
|
+
|
|
3
|
+
Directory requirements evolve — treat this as the workflow map and verify against the host’s current submission docs before submitting.
|
|
4
|
+
|
|
5
|
+
## Contents
|
|
6
|
+
|
|
7
|
+
- Readiness gate
|
|
8
|
+
- ChatGPT apps directory
|
|
9
|
+
- Claude connectors directory
|
|
10
|
+
|
|
11
|
+
## Readiness gate
|
|
12
|
+
|
|
13
|
+
Before any submission:
|
|
14
|
+
|
|
15
|
+
1. `noodle check --target chatgpt` must be clean — every widget needs `domain` (one https origin per app) and an exact `csp` (hosts require the CSP to list precisely the domains you fetch from).
|
|
16
|
+
2. Audit tool responses in developer mode: run realistic prompts and strip anything not strictly needed — PII, internal identifiers (session/trace/request IDs, internal account IDs), and any secrets.
|
|
17
|
+
3. The server must be deployed and publicly reachable: `noodle deploy`, confirm with `noodle open --print` and `noodle smoke`. Reviewers connect to the real endpoint — never submit a placeholder or loopback URL, and the access mode must not be `owner-only` (`noodle access set`).
|
|
18
|
+
4. Polish the listing surface: tool descriptions, widget titles, and the `server` branding tokens are what reviewers and users see.
|
|
19
|
+
|
|
20
|
+
## ChatGPT apps directory
|
|
21
|
+
|
|
22
|
+
Submit from the OpenAI developer dashboard (platform.openai.com → Apps):
|
|
23
|
+
|
|
24
|
+
- Complete organization identity verification first (individual or business) — it is enforced at review time.
|
|
25
|
+
- The submission form asks for the app name, logo, description, company and privacy policy URLs, MCP server URL and tool information, screenshots, test prompts with expected responses, and localization details.
|
|
26
|
+
- One version may be published and one in review at a time; to revise a pending submission, cancel the review and resubmit rather than creating a new app.
|
|
27
|
+
- Review combines automated checks and manual evaluation; rejections come with feedback — fix and resubmit, or reply to appeal. An approved app is also distributed as a Codex plugin.
|
|
28
|
+
|
|
29
|
+
## Claude connectors directory
|
|
30
|
+
|
|
31
|
+
Anthropic runs a connectors directory for Claude; submission goes through Anthropic’s published process (see the Anthropic connectors directory FAQ on support.claude.com). The same readiness gate applies: deployed public endpoint, clean `noodle check`, and graceful degradation where Apps rendering is unavailable.
|