🎃 Export a single connector as JSON or YAML, and accept YAML on import
I maintainer di solito rispondono entro 1 giorno
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 4/5
- Tempo stimato
- 1-2 giorni
- Idoneità per principianti
- 62/100
- Tipo di issue
- Funzionalità
- Chiarezza
- Specificata chiaramente
- Stato di attività
- Attiva
- Stack tecnologico
- nextjs, nodejs, typescript
- Ambito
- api, backend, documentation, frontend
Direzione di ricerca
Start in packages/backend/src/connectors/connectors.controller.ts: read exportAll (around lines 867-917) and importAll (1461-1553), then extract the per-connector mapping into a shared function used by both export endpoints. Add GET /api/connectors/:id/export with a JSON or YAML format, and POST /api/connectors/import that parses content with js-yaml. Done when the round-trip spec in connectors.import-all.spec.ts-style tests passes, npx jest src/connectors is green, and the Export menu and .yaml import work in packages/frontend/src/app/connectors.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Part of the October Challenge #997.
Why
People who build a connector by hand want to move it: from a test instance to production, from one workspace to another, from self-hosted to Cloud, or into a Git repository so a colleague can review it. Today export and import only work for all connectors of a workspace at once, and only as JSON. YAML is easier to read and to diff in a pull request, especially with long tool descriptions and request templates.
What already exists (do not rebuild it):
GET /api/connectors/export-all(connectors.controller.ts:867-917) returns{ version, exportedAt, secretsIncluded, connectors: [...] }.authConfigis never exported. Secret env vars and headers are exported only to admins; for other roles they are blanked and named inmaskedEnvVars/maskedHeaders(toPublicConnector,connector-secrets.util.ts:267).POST /api/connectors/import-all(:1461-1553) skips a connector whose name already exists in the organization, checks the licence and trial limit per connector, and reloads tools.ImportAllDto(:505-535) accepts the export envelope as downloaded. The global ValidationPipe rejects unknown properties, so a single-connector file must have exactly the shape of oneexport-allentry.- The Connectors page has "Export" and "Import" buttons (
connectors/page.tsx:139-181,:219-243). The connector detail page has no export. js-yaml4 is already a backend dependency (packages/backend/package.json:64), used by the OpenAPI parser to accept JSON or YAML (parsers/openapi.parser.ts:7,:166-185). The frontend has no YAML library.
Self-hosted vs Cloud
- Self-hosted: enabled in Community and Business. No
ee/code. - Cloud (
DEPLOYMENT_MODE=cloud): enabled, with the same rules asexport-all/import-all. Each imported connector counts against the workspace's licence or trial limit throughlicenseGuard.checkCanCreateConnector, exactly as inimport-all. YAML is parsed on the backend, within the 10 MB body limit (main.ts:53). - Who can use it: export, any member of the connector's organization (
assertOrgMatch,:583-587), with secret values only forADMIN, as inexport-all. Import, any role exceptVIEWER(assertCanCreate,:589-593). When an admin's file contains secrets (secretsIncluded: true), the UI says that the file holds plaintext credentials and must be stored like a password.
What to build
- One mapping: extract the per-connector object built in
exportAllinto a function (for exampletoExportEntry(connector, includeSecrets)) used by both export endpoints, so the formats cannot drift. - Export:
GET /api/connectors/:id/export?format=json|yaml(defaultjson). It returns the same envelope asexport-allwith one entry inconnectors, so the file is accepted by every import path. YAML viayaml.dump(data, { schema: CORE_SCHEMA, noRefs: true, lineWidth: -1 })withContent-Type: application/yaml. Both formats withContent-Disposition: attachment; filename="<connector-slug>.anythingmcp.<json|yaml>". - Import of JSON or YAML text:
POST /api/connectors/importwith{ content: string }, holding anexport-allfile or a single-connector file. Parse withyaml.load(content, { schema: CORE_SCHEMA }): JSON is valid YAML, so one parser covers both, andCORE_SCHEMAkeepsexportedAta string instead of turning it into aDate. Validate the result againstImportAllDtowithplainToInstance+validate(whitelist,forbidNonWhitelisted), then run the same logic asimport-all: move its loop into a method both endpoints call, and return the same result (message,created,skipped,tools,errors). A parse error returns 400 with the line and column. - UI:
- Connector detail page header (
connectors/[id]/page.tsx:768-780): an "Export" menu with "JSON" and "YAML". Download withfetch+blob()likehandleExportAll(connectors/page.tsx:139-160), and show the same message when secrets were withheld. - Connectors page import dialog (
connectors/page.tsx:162-181,:271-300): the file input (:288) accepts.json,.yaml,.yml, and the dialog sends the raw text to the new endpoint instead of callingJSON.parsein the browser. Rename "Import from JSON" (:220,:241) to "Import from file".
- Connector detail page header (
- Docs: add
export-all,import-alland the two new endpoints to the Connector Endpoints table indocs/api-reference.md:75-90, with a short YAML example.
Where to look
packages/backend/src/connectors/connectors.controller.ts:430-503(ImportConnectorDto),:505-535(ImportAllDto),:583-603(assertOrgMatch,assertCanCreate,assertCanWrite),:867-917(exportAll),:1461-1553(importAll).packages/backend/src/connectors/connector-secrets.util.ts:267:toPublicConnector()masking.packages/backend/src/connectors/parsers/openapi.parser.ts:166-185: existing JSON-or-YAML decoding.packages/backend/src/connectors/connectors.import-all.spec.ts:116,:178: tests that anexport-allfile imports as downloaded and stays in the caller's organization; copy them for the new endpoints.packages/frontend/src/app/connectors/page.tsx:139-181,:219-243,:271-300;packages/frontend/src/app/connectors/[id]/page.tsx:768-780.packages/frontend/src/lib/api.ts:422-425:exportAll/importAllclients.
Acceptance criteria
- Round-trip spec: export one connector as JSON and as YAML, import both into a second organization, and get the same name, type, base URL, config, headers, env vars (admin export) and tools.
- A single-connector JSON file is also accepted by the existing
POST /api/connectors/import-all. - For non-admins, secrets are blanked and listed in
maskedEnvVars/maskedHeaders;authConfignever appears in either format (asserted in a spec). - Exporting another organization's connector returns 403; a viewer gets 403 on import; invalid YAML returns 400 with line information; a file with an unknown property is rejected in YAML as it is in JSON.
-
cd packages/backend && npx jest src/connectorspasses. - Playwright test: the Export menu on the connector page requests
format=yaml, and the import dialog accepts a.yamlfile (cd packages/frontend && npm run test:e2e). -
docs/api-reference.mdupdated.
Out of scope
- A collision policy (rename or replace on a name clash). Import keeps today's behaviour: a connector whose name exists is skipped.
- Exporting more fields than
export-alldoes today (non-secretauthConfigkeys,healthcheckPath,instructions, tool annotations). That changes the DTO and needs its own design. - Duplicating a connector or a tool within a workspace.
- YAML output for
export-all.
Size
M (1–2 days)
How to claim
Comment "I'd like to work on this" and we'll assign you. Rules in #997.
- Lingua principale
- TypeScript
- Stelle
- 856
- Fork
- 82
- Merge medio
- 7h 30m
- PR unite (30g)
- 121
Preparare l'ambiente
Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di HelpCode-ai/anythingmcp
-
good first issue hacktoberfest
Difficoltà 2/5 Mezza giornata Idoneità per principianti 70/100
HelpCode-ai/anythingmcp#996 ·
I maintainer di solito rispondono entro 1 giorno
-
good first issue hacktoberfest
Difficoltà 2/5 Mezza giornata Idoneità per principianti 72/100
HelpCode-ai/anythingmcp#995 ·
I maintainer di solito rispondono entro 1 giorno
-
enhancement good first issue hacktoberfest help wanted
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
HelpCode-ai/anythingmcp#982 ·
I maintainer di solito rispondono entro 1 giorno
-
good first issue hacktoberfest
Difficoltà 2/5 1-3 ore Idoneità per principianti 88/100
HelpCode-ai/anythingmcp#745 ·
I maintainer di solito rispondono entro 1 giorno
-
🐣 Good first issue: contribute a new MCP adapterForse di nuovo libera @7k777 l’ha presa 21 giorni fa e non c’è nessuna pull request aperta. Apertaenhancement good first issue hacktoberfest help wanted
Difficoltà 2/5 1-3 ore Idoneità per principianti 85/100
HelpCode-ai/anythingmcp#150 · 18 commenti ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di HelpCode-ai/anythingmcp
Issue simili
-
enhancement
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 80/100
alunduil/projects-v2-sync#21 ·
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 85/100
-
enhancement minor
Difficoltà 2/5 1-3 ore Idoneità per principianti 74/100
testcontainers/testcontainers-node#1539 ·
I maintainer di solito rispondono entro 1 giorno
-
bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 70/100
christopher-buss/eslint-plugin-flawless#72 ·
I maintainer di solito rispondono entro 1 giorno
-
cleanName keeps a state code that's joined to the word before it (SavannahGa → "Savannah Ga")Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
openwatersio/slackwater-database#281 ·
I maintainer di solito rispondono entro 1 giorno