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:
- Send the intended arguments and a unique
idempotencyKey, withoutapproved. - Show the returned preview to the user and obtain explicit approval.
- Repeat the unchanged arguments with
approved: trueand the returnedapprovalToken.
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. Requirescontent:readand portal settings permission.update_portal_branding({ expectedUpdatedAt, input, idempotencyKey })updates onlyhomeTitle,homeDescription,homeLogo,menuStyle,candidatePortalHomePath,candidatePortalHasPropertiesPathandcandidatePortalHasServicesPath. Requirescontent:writeand portal settings permission. Translations merge with existing locales; omitted fields stay unchanged.menuStyleacceptsone-page,iconsorlabels; the one-page mode hides navigation tabs. The homepage path acceptspropertiesorservices. A non-emptyhomeLogomust reference an existing non-deletedportal-logomedia 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. Requirescontent:writeand 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, andnextOffset. Requirescontent:readand portal content permission.get_content_item({ contentId })returns one Content item and itsupdatedAt. Requirescontent:read.update_content_translations({ contentId, expectedUpdatedAt, input, idempotencyKey })mergestitle,descriptionandlabeltranslations after approval. Requirescontent:writeand portal content permission. Existing locales and non-translation fields stay unchanged. The portal primary locale determinesdefault. 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()andget_project_draft({ draftId })return active drafts and revisions.create_project_draft({ input, projectId?, expectedUpdatedAt?, idempotencyKey })creates a draft. For an existing project, first callget_projectand supply itsupdatedAtasexpectedUpdatedAt.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 returnsdraftFileId.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 areexactandcontains, 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()andget_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 existingschedule-thumbnailmedia 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 latestupdatedAtbefore 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.