Sparki Docs

Configure projects through MCP

Prepare property and service drafts, upload images, connect schedules and publish with explicit approval.

Configure projects through MCP

These authenticated tools configure the portal connected through OAuth at https://api.sparki.app/external-ai/mcp. They are separate from the public property API. Never place administrative OAuth tokens in browser code or Framer CMS fields.

Availability depends on the API deployment and the connector's discovered catalog. Use tools/list as the source of truth. A missing tool cannot be enabled by sending its name manually.

Permissions and approval

Project reads require projects:read; project drafts, image uploads and publishing require projects:write. Schedule tools require schedules:read or schedules:write. The connected user must also have the corresponding portal or schedule permission. Tools cannot switch portals by supplying a different portal ID.

Every write follows the same sequence:

  1. Send the intended arguments and a unique idempotencyKey, without approved.
  2. Show the returned preview to the user and obtain explicit approval.
  3. Repeat the unchanged arguments with approved: true and the returned approvalToken.

Approval expires after ten minutes and is bound to the user, grant, portal, tool and arguments. A changed request needs another preview. Publishing and adding bookable availability each require their own approval.

Retry a completed request with the same arguments and key to retrieve its result. Do not use a new key after a timeout. A running or uncertain operation stops further execution and requires inspection in the dashboard. This prevents duplicate projects when a save succeeds but the response or a later publication step fails.

Tools

  • get_portal_branding() reads only the connected portal's homepage title, description, managed logo, menu style and property/service navigation settings. Requires content:read and portal settings permission.
  • update_portal_branding({ expectedUpdatedAt, input, idempotencyKey }) updates only homeTitle, homeDescription, homeLogo, menuStyle, candidatePortalHomePath, candidatePortalHasPropertiesPath and candidatePortalHasServicesPath. Requires content:write and portal settings permission. Translations merge with existing locales; omitted fields stay unchanged. menuStyle accepts one-page, icons or labels; the one-page mode hides navigation tabs. The homepage path accepts properties or services. A non-empty homeLogo must reference an existing non-deleted portal-logo media URL in this portal; an empty string removes it. Changes apply immediately after approval.
  • upload_portal_logo({ expectedUpdatedAt, filename, mimeType, base64, idempotencyKey }) uploads and assigns a managed homepage logo. Requires content:write and portal settings permission. Supports JPG, JPEG, PNG, WebP and SVG with the existing portal-logo sanitizer, at most 2,560,000 bytes. Preview never uploads. The previous media is preserved; other branding and homepage settings stay unchanged.
  • list_content_items({ offset?, limit? }) lists existing Content items, raw translations, and nextOffset. Requires content:read and portal content permission.
  • get_content_item({ contentId }) returns one Content item and its updatedAt. Requires content:read.
  • update_content_translations({ contentId, expectedUpdatedAt, input, idempotencyKey }) merges title, description and label translations after approval. Requires content:write and portal content permission. Existing locales and non-translation fields stay unchanged. The portal primary locale determines default. This updates the existing item immediately, not a project draft. Reconnect with the new scopes after deployment.

Project read/list responses retain their existing text fields and also expose titleTranslations, descriptionTranslations, longDescriptionTitleTranslations and longDescriptionTranslations for auditing every stored locale.

  • list_project_drafts() and get_project_draft({ draftId }) return active drafts and revisions.
  • create_project_draft({ input, projectId?, expectedUpdatedAt?, idempotencyKey }) creates a draft. For an existing project, first call get_project and supply its updatedAt as expectedUpdatedAt.
  • update_project_draft({ draftId, revision, input, idempotencyKey }) patches an MCP-created draft. Omitted fields remain unchanged; supplied arrays replace their field. Translation locale values merge.
  • upload_project_draft_image({ draftId, revision, filename, mimeType, base64, idempotencyKey }) stages a private image and returns draftFileId.
  • set_project_schedules({ draftId, revision, schedules: [{ id }], idempotencyKey }) stages existing schedule connections.
  • set_project_url_matchers({ draftId, revision, urlMatchers: [{ mode, value }], idempotencyKey }) stages website page matching. Modes are exact and contains, using the dashboard's path normalization. This does not edit website integration settings.
  • publish_project_draft({ draftId, revision, idempotencyKey }) publishes the approved revision, including images, connections and URL rules. Existing CRM links remain intact.
  • list_schedules() and get_schedule({ scheduleId }) return accessible parent schedules, timestamps and configured availability, not customer records.
  • create_schedule({ name, description?, idempotencyKey }) creates an empty parent schedule.
  • update_schedule({ scheduleId, expectedUpdatedAt, name?, description?, idempotencyKey }) updates schedule metadata only.
  • upload_schedule_portrait({ scheduleId, expectedUpdatedAt, filename, mimeType, base64, idempotencyKey }) uploads and assigns a parent schedule portrait after approval. It uses the existing schedule-thumbnail media type. The old media asset is preserved, and availability and bookings stay unchanged. Only an editable parent schedule in the connected portal is accepted. Read its latest updatedAt before preparing the upload.
  • add_schedule_availability({ scheduleId, expectedUpdatedAt, timeZone, date, recurringDayOTheWeek?, slots, idempotencyKey }) adds bookable slots without replacing existing slots or bookings.

Write calls also accept approved and approvalToken as described above. Consult the discovered JSON schemas for exact supported fields and limits.

Read the current portal branding before each update or logo upload and supply its updatedAt as expectedUpdatedAt. The operation rechecks that timestamp under a portal write lock. Logo assignment, setting updates and their idempotency receipt commit together. The existing portal cache invalidation runs after approved commits. These tools cannot select another portal, change colors/themes, credentials, billing, customer records, or unrelated settings. To preserve the homepage, omit its settings. For a complete agency rename, include the new title in each stored locale that should change, including the portal's primary locale. Existing omitted locales are preserved.

Property or appointment-service example

{
  "idempotencyKey": "office-draft-2026-09-19",
  "input": {
    "title": { "default": "Office appointment", "enGB": "Office appointment" },
    "transactionType": "service",
    "category": "other",
    "status": "available",
    "visibility": "always-shown",
    "requiredAppointmentUnits": 1
  }
}

For properties, use to-sell, rent-out or portfolio-item and a supported property category. Translations use flat locale objects with explicit default text, such as enGB, nlNL and esES. Currency follows the existing project model and is not a new per-request setting. Do not invent an office address or default availability.

An existing dashboard draft is readable but cannot be overwritten by these MCP tools. Complete or discard it in the dashboard before creating an MCP draft for that project. MCP publication uses the existing project validation and plan limits.

Form and bidding configuration

create_project_draft and update_project_draft accept existing workflowId and preValidationWorkflowId values. Both forms must belong to the connected portal. workflowId accepts GENERAL or BIDDING; preValidationWorkflowId accepts only PRE_VALIDATION. Send null to remove a connection. These tools attach existing forms, not create or edit forms.

To stage bidding, pass settings: { isBiddingActive: true, biddingStatus: "open" }. Supported statuses are not-started, open, closed and cancelled. Other stored settings stay unchanged. Publishing an approved draft can enable public bidding. No public bid-log setting is exposed. Preview, revision, portal permissions and plan checks still apply. Browser-created drafts must be completed in the dashboard; MCP cannot adopt or publish them.

If Content tools are denied after reconnecting, check the registered client's allowedScopes. A new consent cannot exceed that list. Register a client allowing content:read and content:write, then reconnect and approve the requested scopes. Existing clients and live grants are never expanded automatically.

Images

get_project and list_projects return a separate thumbnail media reference or null. To set it, stage an image with upload_project_draft_image, then pass input: { thumbnail: { draftFileId: "returned-file-uuid", title: "Cover" } } to update_project_draft. An existing thumbnail from the same project can use { id }. Gallery image IDs cannot be converted into thumbnails; upload a separate copy. Omitting thumbnail preserves it; thumbnail: null removes it after publication. Gallery order stays unchanged. The usual preview, revision and publication approvals apply.

get_project also returns the published ordered images gallery, native details, currency, city, state, country, requiredAppointmentUnits and urlMatchers. Each gallery entry includes its media ID, URL, order, title, description and caption. Deleted and non-gallery media are excluded. These values come from the published project, not its draft. Project schedules include their parent schedule identity and portrait when connected through a child schedule. get_schedule and list_schedules include raw translated names, thumbnailId, and the portrait media reference.

Portrait uploads use the same JPG, JPEG, PNG and size limits as project uploads. Previewing never uploads a file. Approval is bound to the exact image bytes and schedule timestamp. The schedule assignment and idempotency receipt commit together. If an upload or commit has an uncertain outcome, keep the same idempotency key and inspect it before trying again. No existing portrait is deleted automatically.

Use JPG, JPEG or PNG, at most 2,560,000 bytes per image. Content, filename and MIME type must agree. The API does not fetch remote URLs. Upload bytes are not recorded in the MCP audit log.

Stage the image, then include its reference in the draft's ordered images array:

{
  "images": [
    {
      "draftFileId": "returned-file-uuid",
      "title": "Living room",
      "description": "Living room with windows overlooking the garden"
    }
  ]
}

The existing image title, description and caption fields retain their current meaning. An array can contain up to ten images. Existing images must belong to the same project; use their id instead of draftFileId. Preserve existing entries in the array when adding another image. Private staged uploads are not public until publication. Floor plans and thumbnails already on the project are preserved.

Availability

slots contains objects such as { "time": "10:00", "availableCount": 1 }. date is YYYY-MM-DD; recurring weekdays use Sunday through Saturday. Use an IANA timezone such as Europe/Amsterdam or Europe/Madrid.

The current schedule model stores local wall-clock date/time values, not a timezone per schedule. The tool validates the supplied timezone and rejects nonexistent times on the supplied date. It does not convert times or change the calendar-sync timezone. Confirm that the supplied timezone matches the schedule's intended zone. Recurring availability follows the existing dashboard recurrence behavior.

Creating a schedule alone does not enable booking. Publishing a project connected to an already-populated schedule can expose its existing availability. Adding slots to a connected schedule activates those slots immediately after separate approval. No tool here creates an appointment, sends a message, configures an external calendar provider or changes billing settings.

Deployment checklist

Publication commits the project, completed draft and idempotency receipt in one database transaction. If that transaction fails, retry the same approved request with the same key while its approval is valid. A completed retry returns the original project ID. Private-file cleanup happens after commit and cannot undo publication. Existing URL matching rules and the default schedule are preserved on unrelated edits.

Deploy the API code with the provisioning-operation migration before using write tools. Refresh connector discovery after deployment. Reconnect and consent to new schedule scopes when needed; existing grants do not gain them automatically. An older OAuth client's allowed-scope list may also need updating by its administrator, or a new client registration, before it can request those scopes.

Portal branding uses existing content:read and content:write scopes, and still requires portal settings permission. If a connected grant lacks those scopes, reconnect the existing connector and consent to them. No new OAuth scopes or migration are introduced by the branding/portrait tools. If the client disallows content scopes, its administrator must update the client or register an appropriate replacement first.

Verify the discovered tool schemas, then test with an isolated demo portal. Confirm draft creation, image staging, explicit publication, URL matching and separately approved availability. Never test by booking an appointment for a real customer.

On this page