formbasedocs
Gå til appenAppen

Utviklere

MCP-server

Model Context Protocol-serveren (MCP) lar AI-agenter lese og redigere formbase-skjemaene dine med rike, schemadrevne verktøy.


Hva det er

MCP er en åpen standard for AI-verktøy som kobler til eksterne tjenester. formbase tilbyr et hostet MCP-endepunkt som enhver MCP-kompatibel klient kan koble til, inkludert Claude Code, Claude desktop og Cursor.

Tilkobling

text
URL:  https://api.formbase.so/api/mcp   (POST, streamable HTTP)
Auth: Bearer <token>

To typer bearer-token fungerer:

  • API-token (fb_…) — opprettet fra API-tokens. Best egnet for personlig bruk og rask oppsett.

  • OAuth-tilgangstoken (fbo_…) — utstedt av OAuth-flyten. Best egnet for tredjepartsapper som kobler til på vegne av en bruker.

Begge er bundet til nøyaktig ett arbeidsområde og når de samme verktøyene. Et verktøykall som navngir et annet arbeidsområde, eller et skjema i ett, feiler med FORBIDDEN. OAuth-tokens har også scopes (mcp:read, mcp:write, offline_access), men ingen verktøy er i dag låst til dem — behandle ethvert token som full tilgang innenfor sitt arbeidsområde.

Verktøykall er begrenset til 120 per minutt per token, delt med API-et: bare tools/call bruker av budsjettet, mens initialize, tools/list, prompts/ og resources/ er gratis. Over budsjettet returnerer kallet fortsatt HTTP 200 med et mislykket verktøyresultat som bærer RATE_LIMITED og en retryAfterMs — poll på en timer, aldri i en løkke.

Hvor du får et token

Åpne OAuth og API-nøkler i arbeidsområdets sidepanel for å opprette API-tokens og se tilkoblede OAuth-apper. Se API-tokens for en trinn-for-trinn-guide.

Kjerneverktøy

Alle verktøy annonseres på tools/list når en klient kobler til. Klienter som laster skjemaer ved behov, som Claude Code, henter det fullstendige skjemaet for et verktøy når en oppgave trenger det. Tabellen nedenfor dekker kjerneverktøyene de fleste oppgaver starter med; load_tools (kataloger) og load_skill (domeneguider) dokumenterer resten.

VerktøyHva det gjør
form_listList skjemaer i et arbeidsområde. Støtter mappefilter, uskarpt navnesøk og markørpaginering.
form_getHent fullstendige detaljer for et skjema: spørsmål, cover, logo og en forhåndsvisnings-URL.
form_createOpprett et nytt tomt skjema i et arbeidsområde. Returnerer en forhåndsvisnings-URL for live-redigering.
form_updateOppdater skjemametadata: navn, mappe, emoji, cover eller logo.
form_deleteMyk-slett et skjema (flyttes til papirkurv, tilbakekaller delingslenker).
form_publishPubliser et skjema slik at det kan motta svar. Idempotent.
workspace_listList alle arbeidsområder tilgjengelige for tokenet ditt.
workspaceFolder_listList mapper i et arbeidsområde.
formSubmission_listList innsendinger for et skjema med paginering. Inkluderer kladder på Pro og Business; Gratis lister bare fullførte svar.
fields_listLister feltnøklene en forespørsel kan adressere på et publisert skjema, hver med verditype, alternativnøkler og en usage-linje. Kall den før request_create.
request_createTildel et publisert skjema til én navngitt mottaker: prefill, låste felt, context, levering, utløp, og en valgfri callback.
request_getLes én forespørsel: status, tidslinje, og — når den er fullført — svar nøkkelsatt etter feltnøkkel, pluss display.
request_listList forespørsler for et skjema eller en hel arbeidsområde, filtrert etter status, outcome, eller din egen eksterne ID.
editor_getDocumentHent den fullstendige dokumentstrukturen til et skjema: alle elementer, typer og egenskaper.
editor_updateElementRediger et eksisterende skjemaelement: erstatt teksten, endre egenskaper (tittel, obligatorisk osv.) eller flytt det.
editor_deleteElementFjern et element fra skjemaet.
editor_insertTextQuestionSett inn et kort eller langt tekstspørsmål. Hver spørsmålstype har sitt eget innsettingsverktøy med et presist skjema.
editor_insertContactQuestionSett inn et e-post-, telefonnummer- eller nettstedURL-spørsmål.
editor_insertNumberQuestion · editor_insertDateQuestionSett inn et tall- eller datospørsmål.
editor_insertRadioQuestion · editor_insertCheckboxQuestion · editor_insertSelectQuestionSett inn enkeltvalg (radio), flervalg (avkrysning) eller nedtrekksspørsmål.
editor_insertDecisionQuestionSett inn beslutningsspørsmålet: valget godkjenn / avslå / endringer der svaret blir et forespørselsutfall. Et radiospørsmål bygget for hånd gir aldri et slikt utfall.
editor_insertRatingQuestion · editor_insertLinearScaleQuestionSett inn et stjernebedømmings- eller lineærskala-spørsmål.
editor_insertHeader · editor_insertParagraph · editor_insertImage · editor_insertPageDividerSett inn ikke-spørsmålsinnhold: overskrifter, avsnitt, bilder og sideskift.
load_toolsLast dokumentasjon for en verktøykatalog. Returnerer skjemaer og bruksmønstre for grupperte verktøy.
load_skillLast en domenekunnskap-guide (temaer, spørsmålstyper, logikregler osv.).

Flere innsettingsvarianter — klokkeslett, filopplasting, signatur, betaling, matrise/rutenett, rangering, bildevelger, veksleknapp, tabell, liste, rad, beregnet felt, skjult felt, innebygd variabel, innebygd innhold (editor_insertEmbedded for YouTube, Google Maps eller iframe-innbygging) og en betinget logikkblokk (editor_insertLogic) — er også på tools/list. Last load_skill(“question-types”) for hele settet, med verktøynavn og felt for hver type. Betinget logikk redigeres med editor_setLogic i editor-actions-katalogen.

Verktøykataloger

Disse verktøyene er også på tools/list. Kjør load_tools med et katalognavn for å få utvidet dokumentasjon (intro, fullstendige skjemaer, bruksmønstre, kanttilfeller) for de grupperte verktøyene, og kall dem deretter direkte.

KatalogInkluderte verktøy
form-dataformAnalytics_get — aggregerte målinger (visninger, innsendinger, fullføringsrate, fordeling etter enhet, land, nettleser, kilde). Krever Pro- eller Business-planen; uten den feiler kallet med en melding som nevner planen.
form-appearanceformTheme_get, formTheme_set, form_update — temaer per modus (lys og mørk), pluss cover og logo via form_update.
form-behaviorformSettings_get, formSettings_update — varselsmeldinger, fullføringsomdirigering, passord, oppbevaring, språk, betaling.
form-sharingformShareLink_list, formShareLink_create, formShareLink_update — CRUD for delingslenker med støtte for egendefinert domene.
form-translationstranslationLanguage_list, translationDraft_get, translationDraft_update, translationDraft_publish, translationLanguage_delete — flerspråklig kladd-og-publiser-arbeidsflyt. Å publisere en tom kladd er eneste måte å avpublisere et språk på.
form-lifecycleform_unpublish, form_restore — livssyklusoperasjoner utover kjernens publisering og sletting.
workspace-managementworkspaceFolder_create, workspaceFolder_update, workspaceFolder_delete — mappe-CRUD utover kjernens liste-verb.
editor-actionseditor_formatText, editor_setLogic, editor_testLogic — tekstformatering, redigering av betinget logikk og logikksimulering.
request-lifecyclefields_list, request_create, request_get, request_list, request_cancel, request_remind, request_replayCallback, document_create — hele forespørselsoverflaten: trekk tilbake en ventende forespørsel, purr på mottakeren, spill av på nytt en callback som aldri kom frem, reserver en dokumentopplasting for én forespørsel.
editor-insertsDen lange halen av editor_insert*-verktøy: klokkeslett, veksleknapp, fil, signatur, dokumentblokk, matrise, rangering, betaling, avtale, bildevelger, innebygd innhold, tabell, liste, rad, beregnet felt, skjult felt, gjentakende gruppe, logikk og variabel.

Katalogen request-lifecycle lister alle de åtte forespørselsverktøyene fordi in-app-chatten annonserer et mindre kjernesett. Over dette endepunktet er alle åtte allerede på tools/list, så det katalogen legger til er dokumentasjonen.

Ferdigheter (domenekunnskap)

Ferdigheter er innebygde guider agenten kan laste via load_skill. De gir domenekunnskap som hjelper agenten med å ta bedre beslutninger — ikke verktøyskjemaer, men designråd og feltssemantikk.

FerdighetHva den dekker
question-typesAlle spørsmålstyper, feltene deres og når man bør bruke hver enkelt.
logic-rulesBetinget logikk: operatorer, handlinger, kombinatorer og kanttilfeller.
editing-flowsMønstre for å bygge skjemaer: rekkefølge, sideskift, piping.
form-best-practicesUX-retningslinjer for effektivt skjemadesign.
form-themesTemastruktur, tokenreferanse og stilretningslinjer.
form-settingsInnstillingsreferanse: varsler, e-postmaler, variabler.
analyticsDefinisjoner av målinger og hvordan man tolker skjemaanalyse.
toon-formatKompakt utdataformat for strukturert datavisning.
requestsForespørsler fra start til slutt: feltnøkler, verdiformer for prefill, levering, per-forespørsel-dokumenter, callbacks, polling og feilgjenoppretting.

Forespørsler

En forespørsel tildeler ett publisert skjema til én navngitt mottaker, med sin egen lenke, sine egne forhåndsutfylte svar, og sitt eget utfall. Det er slik en agent ber et virkelig menneske om noe og finner ut hva de svarte.

Opprette en forespørsel

Start alltid med fields_list(formId). Den returnerer de adresserbare nøklene til skjemaets nåværende publiserte versjon, hver med en usage-linje som sier hvilket argument nøkkelen hører til i — synlige spørsmål går i prefill, skjulte felt i context. Avled aldri en nøkkel fra en spørsmålstittel, og les på nytt etter form_publish.

request_create
json
{
  "formId": "j57...",
  "recipient": { "email": "ada@acme.com", "name": "Ada" },
  "prefill": { "company_name": "Acme", "plan": "pro" },
  "readonly": ["company_name"],
  "context": { "crm_id": "A-42" },
  "metadata": { "run_id": "exec_918" },
  "delivery": "email",
  "expiresAt": 1780000000000,
  "callbackUrl": "https://hooks.acme.com/formbase",
  "idempotencyKey": "po-42"
}

Resultatet inneholder lenken og klokken:

result
json
{
  "id": "kd7...",
  "status": "pending",
  "url": "https://form.formbase.so/r/rq_...",
  "deliveryStatus": "queued",
  "expiresAt": 1780000000000,
  "createdAt": 1747000000000,
  "deduplicated": false,
  "next": "..."
}

delivery er som standard “none”, som gir deg url til å levere selv; “email” sender invitasjonen og krever recipient.email på en Pro- eller Business-plan, eller en av de 10 gratis invitasjonene til en Gratis-konto. readonly låser felt mottakeren ikke kan redigere, og hver låst nøkkel må også være forhåndsutfylt. context tar bare imot nøkler for skjulte felt, mens metadata er ugjennomsiktig bokføring som ekkoes tilbake på request_get og i callbacken. expiresAt er epoke-millisekunder, standard er 30 dager og maks er 365. idempotencyKey er gyldig i 30 dager innenfor arbeidsområden: samme nøkkel med samme body returnerer den opprinnelige forespørselen med deduplicated: true, og en annen body er en konflikt. Hver respons har også en next-linje som forteller agenten hva den skal gjøre videre.

deliveryStatus er not_requested til en invitasjon legges i kø, deretter queued → sent eller failed, og bounced når e-postleverandøren melder om en hard retur eller en klage. Å opprette en forespørsel bruker én enhet av arbeidsområdets månedlige kvote enten mottakeren svarer eller ikke; når den er brukt opp, feiler request_create med MONTHLY_ALLOWANCE_REACHED.

Callbacks eller polling

Med en callbackUrl POST-er formbase én gang per avsluttende hendelse — fullføring, utløp, kansellering — signert med arbeidsområdens signeringshemmelighet for forespørsler. Se Callbacks og signering for nyttelasten og verifiseringsoppskriften.

Autonome agenter bør polle

Signeringshemmeligheten for forespørsler vises kun på siden for legitimasjon i arbeidsområdet ditt — den returneres aldri over MCP eller API-et. En agent som kjører på egen hånd, uten et menneske til å sette opp og konfigurere en mottaker, kan derfor ikke verifisere en callback. La callbackUrl være tom og poll heller request_get(requestId) i størrelsesorden minutter snarere enn sekunder, helt til status forlater “pending”. expiresAt setter en grense for hvor lenge det er verdt å gjøre det.

Testmodus

Send test: true for å øve på hele oppsettet før en ekte kjøring. Lenken åpnes fortsatt og kan fullføres, og callbacken fyrer med “test”: true — men ingenting sendes på e-post uansett hva delivery sier, forespørselen forblir skjult fra Forespørsler-siden og analysetrakten, og innsendingen teller ingen steder: ingen kvote, ingen eksporter, ingen integrasjoner. Testforespørsler vises bare i request_list når du sender includeTest: true. Lenken lukkes innen 24 timer, og på Free kan et workspace opprette 10 testforespørsler per dag.

Dokumenter per forespørsel

For å gi én mottaker en fil — et kontraktsutkast, deres eget tilbud — trenger skjemaet en dokumentblokk, som en forfatter eller en agent setter inn med editor_insertDocumentsBlock. fields_list rapporterer den som type: “documents”. Bytene reiser aldri gjennom et verktøy:

  1. Kall document_create med formId, name, contentType, og den eksakte size i bytes. Du får tilbake { id, name, contentType, size, uploadUrl, expiresAt }. Kun PDF og bilder (ingen Office-dokumenter), 25 MB per fil, og 100 MB dokumenter per forespørsel.

  2. PUT de rå bytene til uploadUrl innen timen, med Content-Type satt til typen du oppga.

  3. Referer den fra request_create: documents: [{ documentId, field?, name? }]. field er dokumentblokkens feltnøkkel, valgfri bare når skjemaet har nøyaktig én slik blokk. name overstyrer visningsnavnet for denne forespørselen.

Blokkens faste dokumenter blir stående, og dine dukker opp under dem, kun for denne mottakeren. request_create verifiserer opplastingen før forespørselen finnes, så DOCUMENT_NOT_UPLOADED betyr at steg 2 ble hoppet over. Én opplasting kan refereres av et hvilket som helst antall forespørsler, og bytene teller mot arbeidsområdens lagring.

Egendefinerte domener

Send domainId til request_create for å utstede lenken på ett av arbeidsområdens egendefinerte domener. IDene kommer fra formShareLink_list, som returnerer dem som availableCustomDomains. Utelater du den, bruker lenken det domenet skjemaet allerede er publisert under.

Lese resultater

request_get returnerer hele forespørselen. Når den er fullført, inneholder answers mottakerens verdier, nøkkelsatt etter feltnøkkel, display de samme nøklene som lesbar tekst, og outcome — godkjent, avvist, eller endringer — er deres avgjørelse når skjemaet har et beslutningsspørsmål. Et callbackFailedAt-tidsstempel betyr at leveringen gikk tom for nye forsøk og at ingenting nådde endepunktet ditt; fiks mottakeren, og kall deretter request_replayCallback, som sender den opprinnelige hendelses-IDen på nytt slik at mottakeren din dedupliserer i stedet for å kjøre på nytt. Etter at skjemaets oppbevaringspolicy fjerner en forespørsel, settes dataPurgedAt, og svarene er borte for godt.

request_list feier gjennom mange på én gang, filtrert etter status, outcome, externalId, og includeTest. Sideinndel med nextCursor: en side kan sjelden komme tilbake med en tom items og hasMore: true, noe som ikke er slutten på listen — send cursoren tilbake og fortsett.

Ressurser og prompter

Hver ferdighet og verktøykatalog er også en MCP-ressurs på skill://<name> — skill://requests, skill://editor-inserts. En klient som støtter resources/list kan bla gjennom og lese dem uten å kalle load_skill eller load_tools. Serveren tilbyr også fire prompter på prompts/list: identity, capabilities, data_tools, og editor_tools.

Verktøy som spør først

Hvert verktøy bærer MCP-hintene readOnlyHint og destructiveHint, avledet fra verbet sitt. Disse verktøyene er merket destruktive, fordi det å angre dem krever et nytt kall eller ikke er mulig: form_delete, form_unpublish, workspaceFolder_delete, editor_deleteElement, translationLanguage_delete, og request_cancel. De fleste klienter spør brukeren før de kjører dem, men ledeteksten er klientens avgjørelse, så sjekk godkjenningsinnstillingene dens hvis du trenger en garantert stopp.

Begrensninger

  • Ingen binæropplastinger via et verktøykall. Bilder settes med URL: covers, logoer og bildeblokker godtar http(s):// eller data:image-URI-er. Et dokument per forespørsel er unntaket: document_create returnerer en opplastings-URL som en klient med HTTP-tilgang kan PUTe filen til (se Dokumenter per forespørsel). For å gjøre en PDF eller et skjermbilde om til et skjema, bruk den innebygde AI-chatten.

  • Ingen arbeidsområde-AI-ferdigheter. Ferdigheter skrevet i formbase er bare tilgjengelige i den innebygde AI-chatten. Serverens egne ferdigheter (load_skill) er tilgjengelige over MCP.

Koble til med et API-token

De fleste klienter logger inn med OAuth: lim inn URL-en uten header og følg Koble til en AI-agent. En klient som ikke kan åpne en nettleser, som et skript, en CI-jobb eller en hodeløs agent, sender i stedet et API-token som en header.

Claude Code, fra kommandolinjen:

bash
claude mcp add --transport http formbase https://api.formbase.so/api/mcp \
  --header "Authorization: Bearer fb_YOUR_TOKEN"

Eller i et prosjekts .mcp.json:

.mcp.json
json
{
  "mcpServers": {
    "formbase": {
      "type": "http",
      "url": "https://api.formbase.so/api/mcp",
      "headers": {
        "Authorization": "Bearer fb_YOUR_TOKEN"
      }
    }
  }
}

Cursor, i .cursor/mcp.json eller ~/.cursor/mcp.json:

mcp.json
json
{
  "mcpServers": {
    "formbase": {
      "url": "https://api.formbase.so/api/mcp",
      "headers": {
        "Authorization": "Bearer fb_YOUR_TOKEN"
      }
    }
  }
}

For å logge inn med OAuth i stedet for et token, bruk

Legg til i Cursor

. Den legger til server-URL-en uten header, og Cursor ber deg logge inn på formbase.

Andre klienter tar samme URL og header; se deres dokumentasjon for hvor.

Bruke OAuth i stedet for API-tokens

En tredjeparts-app som kobler til på vegne av en bruker, bør bruke OAuth i stedet for å be om et innlimt token. formbase er en OAuth 2.1-autorisasjonsserver med obligatorisk PKCE (S256) og opake tokens — ingen JWT-er, ingen implisitt grant. Claude desktop, Claude Code og Claude.ai-nettkobleren oppdager alt dette fra MCP-endepunktet, så det holder å lime inn URL-en uten header: 401-en peker til /.well-known/oauth-protected-resource, og klienten tar det derfra.

Flyten, for en klient du skriver selv:

  1. GET /.well-known/oauth-protected-resource, deretter GET /.well-known/oauth-authorization-server for endepunkt-URL-ene, scopene og de støttede autentiseringsmetodene.

  2. POST /oauth/register med dine redirect_uris (dynamisk klientregistrering, ingen legitimasjon nødvendig). Du får en client_id, pluss en client_secret hvis du ba om noe annet enn token_endpoint_auth_method: “none”. Redirect-URI-er må være HTTPS, eller HTTP på localhost. Registrering er begrenset til 20 per time per IP.

  3. Send brukeren til /oauth/authorize med response_type=code, din client_id, den registrerte redirect_uri, scope=mcp:read mcp:write offline_access, state, og en code_challenge med code_challenge_method=S256. De logger inn, velger ett arbeidsområde, og autoriserer.

  4. Bytt inn koden på POST /oauth/token med grant_type=authorization_code og din code_verifier, innen 60 sekunder. Koder kan bare brukes én gang.

  5. Kall MCP-endepunktet med Authorization: Bearer fbo_…. Tilgangstokens varer i 1 time; refresh-tokens varer i 30 dager og roteres ved hver bruk. Gjenbruk av et brukt refresh-token brenner hele kjeden, så lagre det nyeste.

POST /oauth/revoke (RFC 7009) tilbakekaller et tilgangs- eller refresh-token. En bruker kan også koble fra hele appen fra Tilkoblede apper på siden OAuth og API-nøkler, som dreper alle tokens den har for det arbeidsområdet.

Har du allerede et token for hånden, går det samme sted som en API-nøkkel:

MCP config with OAuth token
json
{
  "mcpServers": {
    "formbase": {
      "type": "http",
      "url": "https://api.formbase.so/api/mcp",
      "headers": {
        "Authorization": "Bearer fbo_USER_OAUTH_TOKEN"
      }
    }
  }
}

Tilkoblede apper

Hver OAuth-tilkobling er listet under Tilkoblede apper på siden OAuth og API-nøkler, med når den ble tilkoblet og sist brukt. Tilkoblinger er personlige: bare brukeren som autoriserte den, ser den, og arbeidsområdeadministratorer kan verken se eller tilbakekalle et annet medlems. Å koble fra trer i kraft umiddelbart. En bruker som forlater eller fjernes fra arbeidsområdet, mister alle sine tilkoblinger til det.

Neste steg