Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 94 additions & 0 deletions docs/ANTHROPIC_SUBMISSION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# Anthropic directory submission (not submitted)

Portal: https://claude.ai/directory/manage → Submit new. It takes two kinds of submission, and
Anthropic asks for both when a plugin points at a server you run:

- **MCP connector**: FTW Cloud's remote server (`https://cloud.ftw.energy/mcp?profile=public`).
- **Plugin bundle**: this repository, read from `.claude-plugin/plugin.json`.

A listing reaches claude.ai, Cowork and Claude Code. Anthropic's `claude-plugins-official`
marketplace is separate and takes no portal submissions; it goes through an Anthropic partner
contact. Fredrik submits; nothing here has been sent. Facts below were checked on 30 Oct 2026.

Sources:

- [S1] Submit a connector: https://claude.com/docs/connectors/building/submission
- [S2] Connector review criteria: https://claude.com/docs/connectors/building/review-criteria
- [S3] Authentication for connectors: https://claude.com/docs/connectors/building/authentication
- [S4] Software Directory Policy: https://support.claude.com/en/articles/13145358-anthropic-software-directory-policy
- [S5] Submit a plugin: https://claude.com/docs/plugins/submit
- [S6] Plugin pre-submission checklist: https://claude.com/docs/plugins/pre-submission-checklist
- [S7] Publish a plugin (Claude Code): https://code.claude.com/docs/en/plugins/publish
- [S8] Anthropic's marketplaces: https://code.claude.com/docs/en/plugins/anthropic-marketplaces

Status: ✅ met, from repo or server facts · ⚠️ open, needs work or a decision · ❓ not checked yet

## Who submits

| Requirement | Answer | Status |
|---|---|---|
| Paid Claude plan; on Team/Enterprise an Owner submits [S1][S7] | Which Claude account Sourceful uses is not known | ❓ |
| GitHub account connected on claude.ai, with push rights to the repo [S5] | srcfl/ftw-plugin is public | ❓ (connect at submission) |
| Agree to the Directory Terms and Policy, maintain security, respond to security issues [S1][S4] | Support: support@sourceful.energy | ⚠️ Fredrik reads and accepts |

## 1. MCP connector (FTW Cloud)

| Requirement | Our answer | Status |
|---|---|---|
| Remote, reachable over `https://` [S1] | `https://cloud.ftw.energy/mcp?profile=public` | ✅ |
| Streamable HTTP transport [S4 §5F] | `mcp.json` declares `streamable-http` | ✅ |
| OAuth 2.0 for authenticated services, 401 discovery metadata [S1][S3][S4 §5D] | Unsigned call returns 401 with `resource_metadata`; authorization server metadata lists PKCE S256, `/oauth/register` (DCR) and client ID metadata documents | ✅ |
| Claude's callback accepted | `https://claude.ai/api/mcp/auth_callback` is accepted (see SUBMISSION.md, "Sign-in for each assistant") | ✅ |
| Every tool has `title` and `readOnlyHint` / `destructiveHint` [S1][S4 §5E] | srcfl/ftw-cloud `internal/mcp/tools.go` sends `title`, `readOnlyHint` and `destructiveHint` for each tool | ✅ in source; ⚠️ check the portal's Tools step shows no flags |
| Split safe and unsafe actions into separate tools [S2] | Reads, `ev_charge_now`, `goal_request` / `car_goal_request` and `setup_*` are separate tools | ✅ |
| Tool names at most 64 characters [S4 §5C] | Longest is `measurement_diagnostics` (23) | ✅ |
| Clear errors, frugal with tokens [S4 §5A–B] | Tools take `hours`, `points`, `lines`, `limit` bounds | ⚠️ reviewer judgment |
| Tested in Claude as a custom connector, every tool called [S1 step 8] | Tested in Grok Bot (see SUBMISSION.md, Testing); not yet in Claude | ⚠️ |
| Reviewer test account, fully populated [S1][S4 D] | Simulated home at https://review.ftw.energy with invitation codes (see REVIEW.md); login only in the portal, never in git | ✅ (Fredrik enters the login) |
| Three or more working example prompts [S4 E] | "How is my home's energy right now?", "Show today's plan", "Battery history last week" (REVIEW.md) | ✅ |
| Own the endpoint and domain [S4 F] | cloud.ftw.energy and ftw.sourceful.energy are Sourceful's | ✅ |
| Documentation URL [S1 step 3] | https://ftw.sourceful.energy, plus this repository | ✅ |
| Privacy policy URL [S1 step 3] | https://ftw.sourceful.energy/privacy#assistants | ✅ |
| Support contact [S1 step 3] | support@sourceful.energy | ✅ |
| Icon [S1 step 3] | `assets/icon.png`, `assets/logo.png` | ✅ |
| Listing: name ≤100, one-liner ≤200, description ≤2,000, 1–5 categories, slug (permanent) [S1 step 3] | Name "FTW"; one-liner: plugin.json `description`; slug `ftw` proposed | ⚠️ description and categories not written; slug is Fredrik's call |
| Use cases, prerequisites, reads/writes [S1 step 4] | Needs an FTW box at home and the owner's approval; reads by default, writes (short charging, requests) only with a separate grant | ⚠️ write out |
| Company and primary contact [S1 step 5] | Sourceful Labs AB, fredrik@sourceful-labs.com | ✅ |
| Authentication method [S1 step 6] | Required; OAuth with DCR / client ID metadata (no Anthropic-held client) | ✅ |
| Data handling: own API, health data, sponsored content [S1 step 7] | Own API (FTW Cloud and the owner's box); no health data; no sponsored content | ✅ |
| Seven compliance acknowledgments, incl. financial transactions and prompt injection [S1 step 9] | No purchases or payments; tool descriptions mark box data as data, not instructions | ⚠️ Fredrik reads and ticks |
| Allowed link URIs (only if `ui/open-link` is used) [S1] | Not used | ✅ n/a |
| MCP App screenshots [S1] | Not an MCP App | ✅ n/a |

## 2. Plugin bundle (this repository)

| Requirement | Our answer | Status |
|---|---|---|
| Folder with `.claude-plugin/plugin.json` [S6] | Repository root | ✅ |
| Name: lowercase, digits, hyphens, ≤64, not reserved, not taken [S6] | `ftw` | ✅ pattern; ❓ whether the name is free; a short name may be held as look-alike |
| `description`, `author`, `version` set [S6] | Set, version 1.3.0 | ✅ |
| README ≥40 words outside code blocks [S6] | README.md, 664 words in total | ✅ |
| License [S6] | `LICENSE` (MIT) and `license` in plugin.json | ✅ |
| `.mcp.json` valid; remote server has `type` http/sse/ws and an `https://` URL [S6] | `{"type":"http","url":"https://cloud.ftw.energy/mcp?profile=public"}` | ✅ |
| No credentials in any file [S6] | None; the reviewer login lives outside git | ✅ |
| No launchers, lockfiles, hooks or local server commands [S6] | None | ✅ |
| No `.DS_Store` and similar, no symlinks, submodules or LFS [S6] | None found | ✅ |
| Non-image files under 256 KiB, ≤512 files, only text/PNG/JPEG/GIF/WebP/SVG/fonts [S6] | Text and PNG only, well under 512 files | ✅ |
| Skills: valid YAML front matter with a text `description` [S6] | Two skills; `scripts/check.py` checks name and description | ✅ |
| README describes everything the plugin runs, sends or fetches (security scan) [S6] | README names FTW Cloud as the only server | ⚠️ re-read with the scan in mind |
| `claude plugin validate ./ --strict` passes [S5][S7] | Not run: Claude Code is not installed on the box | ❓ |
| Loaded and tried on each surface (claude.ai, Cowork, Claude Code) [S6] | Not done | ⚠️ |
| Extra folders shipped to users | `openai/`, `.cursor-plugin/`, `.agents/` and `docs/` sit in the plugin folder and ship with it | ⚠️ allowed by the checks above; decide if a subfolder is cleaner |

## Gaps to close before submitting

1. Choose the Claude account (paid plan, Owner role on Team/Enterprise) and connect GitHub on claude.ai.
2. Add FTW as a custom connector in Claude, sign in through the reviewer home, call each read tool
and record it, as was done for Grok Bot.
3. Run `claude plugin validate ./ --strict`, then the portal's Validate, and fix any finding.
4. Write the connector listing description (≤2,000 characters), the categories and the use-case text.
5. Decide whether to submit the connector first, then the plugin paired with it, as [S1] and [S5]
suggest.
6. Read and accept the Directory Terms and the seven acknowledgments.

Escalation address for a stuck connector submission: mcp-review@anthropic.com [S1].
57 changes: 56 additions & 1 deletion docs/SUBMISSION.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ submits; nothing here has been sent.
| 9 | MCP Server URL or Public GitHub Repository * (200) | https://github.com/srcfl/ftw-plugin |
| 10 | Brief Description * (600) | below |
| 11 | Testing Instructions * (600) | below; the login is filled in at submission |
| 12 | "I've tested this plugin locally and in-app" * | tick only after a real connection in Grok Bot and in Cursor desktop |
| 12 | "I've tested this plugin locally and in-app" * | Grok Bot: tested 30 Oct 2026 (see Testing). Cursor desktop: not yet tested; tick only after the Cursor steps below pass |

The repository is the better answer to field 9: it carries the MCP address, both skills, the logo,
the terms and privacy links and the MIT license. The MCP address alone is
Expand Down Expand Up @@ -88,3 +88,58 @@ required for all of them.
- Cursor desktop: `cursor://anysphere.cursor-mcp/oauth/callback`. Accepted. The consent page shows it
as a program on this computer and asks the owner to approve only if they started it. Test in a
real Grok Bot and in Cursor desktop before submitting.

## Testing

What was really run, and what is still open. Times are Europe/Stockholm (CET).

### Grok Bot: tested, 30 Oct 2026, 14:45–14:55 CET

Run from a Grok Bot session that already had FTW connected through FTW Cloud's OAuth sign-in, as
two connections to a real home (not the reviewer home):

- the public profile (`https://cloud.ftw.energy/mcp?profile=public`), and
- a connection with the owner's diagnostic grant.

| Check | Result |
|---|---|
| List tools, public profile | 27 tools, the count in field 10 |
| List tools, diagnostic connection | 29 tools: the same 27 plus `api_catalog` and `api_read` |
| `health_get` (public) | OK: version v0.157.3-beta.1, drivers 2 ok / 0 degraded / 0 faulted / 0 offline, meter live, no control block |
| `homes_list` (public) | OK: scopes `ftw.live.read`, `ftw.plan.read`, `ftw.history.read`, `ftw.health.read`; no operations; caps 0 W; grant expiry shown |
| `status` (diagnostic connection) | OK: live grid, solar, battery, car and load readings with sources and ages |
| `plan_get` hours=3 (diagnostic connection) | OK: 15-minute slots with battery and grid power, price and reason codes |
| `api_catalog` (diagnostic connection) | OK: route list, running version and source links |
| Errors | none |

Only read tools were called. No control, goal or setup tool was called. Readings from the home are
not copied here.

Not covered by this run: a fresh sign-in from zero, the invitation-code path on
https://review.ftw.energy, and the two skills' wording in Grok Bot.

### Static checks: passed, 30 Oct 2026

- `python3 scripts/check.py` (with `jsonschema`): "All manifests check out."
- `.cursor-plugin/plugin.json`: name `ftw`, version 1.3.0, MIT, logo `assets/logo.png`.
- `mcp.json` (`streamable-http`) and `.mcp.json` (`http`) both point at
`https://cloud.ftw.energy/mcp?profile=public`.
- Unsigned `initialize` to that URL returns 401 with `WWW-Authenticate: Bearer resource_metadata=…`
and the four read scopes, so a client can discover sign-in.
- `/.well-known/oauth-protected-resource` and `/.well-known/oauth-authorization-server` answer, with
PKCE S256, dynamic client registration and client ID metadata documents supported.

### Cursor desktop: not yet tested

Nobody has run the plugin in Cursor desktop yet. Fredrik runs this before ticking field 12:

1. In Cursor desktop, add the plugin from this repository (or add the MCP server
`https://cloud.ftw.energy/mcp?profile=public` under Settings → MCP).
2. Start sign-in. The browser opens FTW Cloud's consent page. It should name the program as one on
this computer (`cursor://anysphere.cursor-mcp/oauth/callback`).
3. Pick "I have an invitation code", create a read-only invitation at https://review.ftw.energy
(or approve your own box), and paste the code.
4. Check that Cursor returns to the app and shows FTW as connected with 27 tools.
5. In chat, ask "How is my home's energy right now?" and "Show today's plan". Check that `status`
and `plan_get` answer without errors.
6. Write the date, the Cursor version and the result in this section.
Loading