MCP tool surface
Sprig’s interface is Claude, not an API you call directly. The gateway hosts an MCP server
at /mcp; the tools below are what Claude actually has available in a sprig conversation.
Every tool call is attributed to your own signed-in identity and lands in the audit trail.
The gateway uses MCP protocol revision 2026-07-28 over stateless Streamable HTTP.
Tool arguments use JSON Schema. Successful results include the same JSON in MCP
structuredContent and in a text block for clients that do not yet read structured results.
Each tool publishes its own output schema, generated from the platform response contract and
including gateway-added transfer or workflow fields. The tool list also publishes human-readable
titles, behavior annotations, and PNG icons. Input schemas include known closed values, string
patterns, collection bounds, and numeric limits so clients can reject invalid calls before sending
them. Some results include a bounded nextActions list when Sprig knows the exact tool and
arguments for a later step. Claude must still check the action’s when condition before calling it.
Failed tool calls keep a readable text message and also return a structured error object. Its
stable code and retryable flag let clients decide whether to correct input, sign in again, or
retry a temporary platform failure without parsing prose.
Clients using MCP protocol 2026-07-28 can opt into the Tasks extension. Sprig may then return a
task handle for complete_publish while verification continues, and the client polls tasks/get
until it receives the ordinary tool result. All other tools stay synchronous. Clients without the
extension continue to receive the complete_publish result inline. Task handles remain valid for
15 minutes. Cancelling a task stops waiting when possible, but does not roll back publication work
that already reached the platform. A new complete_publish call for the same reserved version is
safe because completion is idempotent.
list_apps, list_sources, list_share_requests, and list_source_access_requests return at
most 50 items by default. Set limit from 1 through 100, then pass the opaque nextCursor result
back as cursor to continue. Cursors work across gateway replicas without server-side session
state. They do not freeze the list, so items can move between pages if the underlying list changes
while you page through it.
Source discovery is role-shaped. Builders see source names, status, exposed entities, readable
fields, API paths, and schema links. Physical server, database, schema, reader-group, grant, and
enforcement metadata is omitted. Ops responses include that administrative metadata under
details.
Discovery
Section titled “Discovery”| Tool | Who | Does |
|---|---|---|
list_apps |
anyone | Lists the apps you own or can build: name, publish state, active version, and canonical URL when active and public app DNS is configured |
list_sources |
anyone | Lists the data sources Ops has exposed to you |
describe_source |
anyone | One source’s entities, served API names and paths, readable fields, and links to its schema resources: REST OpenAPI always, GraphQL only for DAB-served kinds (semantic models have no GraphQL surface and omit the link) |
whoami |
anyone | Echoes the identity the gateway validated from your token - useful to confirm sign-in is working |
get_publishing_status |
anyone (owner) | Returns one app’s publish state, active version, canonical URL when available, last update, and the active version’s source provenance: producedBy (builder-upload or platform-build), sourceRetained, and secretFindings. Versions accepted by the blocking source scan report zero findings |
get_app_source |
anyone (owner) | Returns a short-lived transfer URL and bearer header for the retained source of one of your app’s versions. Downloads stream through the gateway and can resume with HTTP Range. Omit version for the currently active one. Versions published before source retention existed have no source and return a clear error |
Building and publishing
Section titled “Building and publishing”| Tool | Who | Does |
|---|---|---|
begin_publish |
anyone | Reserves a version, creates the app record on first publish, and returns two 15-minute transfer targets: one for the project source archive, one for the built bundle archive. The bundled helper sends resumable 4 MiB blocks through the single transfer host. Both archives are mandatory, described by the flat arguments sourceFormat/sourceSize/sourceSha256 and bundleFormat/bundleSize/bundleSha256 |
complete_publish |
anyone | Verifies and lints the staged source, runs a blocking secret scan, and rejects suspected secrets before source promotion or bundle activation. A clean result durably retains the source, activates the bundle, and returns the canonical app URL when public app DNS is configured. A temporary scanner failure leaves the reservation retryable |
provision_app |
anyone | Gives an app its own serverless database, groups, row-level security, and exposed entities. An optional sources list files one source-access request per registered source id after the provision succeeds, reporting filed, existing, or superseded for each |
request_source_access |
anyone (owner) | Asks for one of your apps to be allowed to read a registered source, which a published app needs because it reads under its own group rather than yours. The reply is the request record: pending is waiting in the Ops inbox and the app cannot read the source yet, approved means the source’s policy approved it on filing and the grant is already live. Requesting an already approved pair re-applies the grant instead of erroring |
share_request |
anyone (owner) | Requests that an app be shared with a group (by groupId or groupName); goes to Ops for approval |
Ops tools (require the Ops role, enforced server-side)
Section titled “Ops tools (require the Ops role, enforced server-side)”| Tool | Does |
|---|---|
register_source |
Registers an Azure SQL Database (default kind), a Fabric Warehouse / lakehouse source (kind: fabric-dw), or a Power BI / Fabric semantic model (kind: fabric-semantic); no source credentials are accepted. SQL-shaped kinds are addressed by logical server name or exact host plus database name; fabric-semantic is addressed by workspaceId and itemId (two GUIDs) and takes no server, database, or schema. kind is fixed once a source is registered. enforcementMode (db-delegated or gateway-enforced) is optional and defaults per kind: azure-sql and fabric-semantic support only db-delegated, fabric-dw supports only gateway-enforced. Attempts schema discovery on every request and reports back one of three outcomes: discovered (schema read; for SQL-shaped kinds the response also carries a required serving-identity grant that must still be applied, before expose_entities, so the platform’s own serving identity can read the source - for fabric-semantic it instead carries the pinned-principal Ops/reader runbook to keep current), grant-required (returns the exact one-off grant for the source DBA / Fabric workspace admin to run), or unsupported (returned when the platform has no way to read that kind of source - a fabric-dw or fabric-semantic source on an installation that was not given the Fabric inputs at install time; the semantic unsupported result still carries the one-time grant runbook to prepare, with reader groups resolved to their Entra object ids). Discovery reads azure-sql and fabric-semantic as the calling Ops user (the semantic read runs over Power BI on-behalf-of, so the model’s own permissions decide what the catalog shows) and fabric-dw as sprig’s own service identity, which is why the kinds have different grant runbooks. Semantic reader groups must be plain security groups; they and the Ops group are pinned to their resolved object ids: a name that later resolves to a different principal is refused until a re-registration that carries both rebindReaderGroups: true (the explicit rebind consent) and the current expectedVersion (the concurrency fence). Removing or rebinding a principal persists its old object id on the source as a pending revocation: every runbook repeats the exact revocation steps until a re-registration carries revocationsApplied: true with the current expectedVersion, which clears the backlog and records an audit fact. Exact retries are safe; updates to display name, schema, or reader groups require the current expectedVersion |
expose_entities |
Exposes selected discovered tables/views from a registered source as read-only entities, mapped to Entra groups. Pass the current source version from describe_source as expectedVersion; stale writes are rejected. Each entity requires as, the exposed name, and fieldExcludes, the complete exclusion list. To preserve an existing exposure, copy name from describe_source into as, never its namespaced apiName, and pass fieldExcludes: [] when no fields are excluded. An MCP update preserves any field allow-list previously reviewed in the admin console and can only narrow it. Regenerates the served data config |
disable_source |
Withdraws a source from service while retaining its registration, discovered schema, and exposed entities. Requires the current expectedVersion |
enable_source |
Runs discovery again and returns a disabled source to service. Requires the current expectedVersion and may return updated DBA grant instructions |
delete_source |
Withdraws a source, then removes its registration, schema, and exposed entities while retaining audit history. Requires the current expectedVersion. A fabric-semantic source with pending principal revocations refuses deletion until they are confirmed; one deleted while principals are still pinned records them in a durable audit fact and returns their final revocation runbook |
list_share_requests |
Lists share requests pending approval: who’s asking, which app, which group |
approve_share |
Approves a pending share request - adds the group to the app’s viewers with zero redeploy |
reject_share |
Rejects a pending share request, optionally with a reason shown to the requester |
list_source_access_requests |
Lists app-to-source access requests waiting on a decision: request id, app, source, who asked, and when. A different inbox from list_share_requests: this one decides what an app may read, not who may open it |
approve_source_access |
Approves one or more pending app-to-source requests. Pass every id in a single call: one batch is one decision and one data-layer configuration roll whatever its size. The grant is read-only over the source’s already-exposed entities, with the same column excludes every other reader gets. The whole batch is refused before anything is written if an id is already rejected or revoked, or a named source is no longer in service; re-approving an approved id converges and re-applies the grant. Reports applied, converged, or superseded per id |
reject_source_access |
Rejects one or more pending requests in one batch, optionally with a reason shown to the app’s owner. Rejecting grants nothing and rolls no configuration, so it is allowed even when the source is out of service; the whole batch is refused if any id is no longer pending. The owner can file a fresh request for the same pair afterwards |
revoke_source_access |
Withdraws one approved app-to-source grant and rolls a data-layer configuration without it. For approved grants only: a request still pending is rejected, not revoked. The record stays with status revoked, so the history remains auditable |
onboard_builder |
Adds a person to the platform’s builder group - their next sign-in works with zero setup |
offboard_builder |
Removes a person’s building rights. Their apps are never deleted; pass a UPN to reassign ownership of everything they own in the same call, or omit it to just see what they own |
App retirement can leave source-owner work that Sprig cannot execute. The
POST /api/admin/apps/{name}/retire response lists it in sourceRevocations as
either sourceKind: azure-sql with ready-to-run sql, or sourceKind: fabric-semantic with the Power BI model and OneLake runbook. The ledger is
written before Sprig changes source grants, so an exact retirement retry returns
the same pending work. After every pending entry for a source has been completed,
re-register it with revocationsApplied: true and the current expectedVersion.
This clears the source’s whole pending revocation ledger and records an audit fact.
delete_source refuses every source kind while this ledger is non-empty.
What’s not there yet
Section titled “What’s not there yet”Conversational data-query tools (query_records, aggregate_records, describe_entities
as a live-query aid) are specified but not implemented; see Building on exposed
data for how querying actually works today.
Supported access
Section titled “Supported access”Use these tools through Claude, or use the documented sprig operator commands. The
operator endpoint is internet reachable so CLI and device-code flows can use it, but it is
not anonymous: requests require a valid Entra bearer token and server-side authorization.
Raw HTTP routes are not a supported integration surface.
Source schema resources
Section titled “Source schema resources”describe_source keeps discovery compact. Each entity includes its served apiName,
same-origin REST path, and readable field names. Ops also receives the physical source mapping
under details. The result links to
two versioned MCP resources for the source:
sprig://sources/{sourceId}/versions/{sourceVersion}/rest/openapi.jsonsprig://sources/{sourceId}/versions/{sourceVersion}/graphql/schema.graphql
Claude reads only the protocol schema it needs. Both resources use the caller’s identity and
the same source and field visibility rules as describe_source. A source change invalidates
the old versioned URI, so Claude must call describe_source again instead of using stale
schema.