Skip to main content

Application integration

Integrate your applications and tools with a running data product in two supported ways: client libraries in your language, and the Model Context Protocol (MCP) endpoint that every product exposes for assistants and MCP-aware clients. Both use the same authentication and API surface as the manifest your data product publishes through the control plane.

The low-level gRPC/HTTP wire protocol reference is for custom runtimes and debugging, not for typical integration work.

Model Context Protocol (MCP)

Each deployment serves MCP on the data product’s HTTP base URL under /mcp. Every API operation is available as an MCP tool with schema-backed arguments and results. You do not configure or deploy a separate “MCP server” per product beyond the running data product itself.

Model Context Protocol (MCP) → — endpoint, tools, and when to use MCP vs libraries.

Client libraries: two-layer model

Each language has the same two-layer shape:

  1. Generic runtime library — a hand-maintained library that implements authentication, gRPC, REST, message chunking, reauthentication, and the internal binary serialization and JSON encodings. It exposes generic IngestClient, OutletClient, and ApiClient types whose payload type is bytes (or the equivalent). The low-level protocol details live under Data plane wire protocols if you need them.
  2. Per-data-product generated client — a small typed wrapper produced by the Dataspine code generator from the data product's published manifest. It depends on the runtime library and exposes typed methods such as placeOrder(...) or subscribeToOrderEvents() that handle the per-operation serialization, the operation IDs, and the strongly-typed request and response classes.

Throughout this section we use the placeholder vocabulary acme (organization) / com.acme.orders (data product namespace and name) / OrderEvent, PlaceOrder, ListOrders (operations and types) for examples. Replace them with your own data product's identifiers.

Language matrix

  • TypeScript — generally available. Two flavors: a Node.js client (@connectrpc/connect-node for gRPC + fetch for REST) and a browser client (grpc-web for gRPC). Per-data-product clients are published as @<your-org>/<data-product>-node-client and @<your-org>/<data-product>-browser-client.
  • Java — generally available. Reactor-based, using Flux<T> for streams and Java 21 sealed records for typed responses. The runtime library is com.dataspine:data-product-client; per-data-product clients are published as com.<your-org>.<data-product>:<data-product>-client.
  • Rust — generally available. tonic-based, async/await with tokio. Runtime crate is dataspine-data-product-client; per-data-product crates are emitted by the generator and consumed via Cargo.toml.
  • Python — upcoming. The runtime package currently only contains configuration/serialization scaffolding; ingest, outlet and API clients are not yet exposed.

When should I use a client library vs. MCP vs. the wire protocol?

  • Default: the per-data-product generated client in your language.
  • MCP: assistants, agents, and any host that already speaks MCP to tools at a URL; see MCP.
  • Generic runtime (when the typed client is missing a behavior you need, e.g. a platform-issued resume offset or a shared internal framework).
  • Wire protocol only for languages we do not ship, hand-written low-level clients, or debugging. See the wire protocol reference. It is an implementation detail, not the product integration path.

Common configuration

Every client library shares the same configuration shape:

  • Endpoint: the regional endpoint of the data product. The control plane derives it per-region and per-data-product (https://<data-product>.<region>.<your-org>.example for REST, the same host for gRPC and gRPC-Web). The TS, Java, and Rust runtime libraries all accept either an explicit endpoint or a configuration object that resolves it.
  • Authentication: a token provider that surfaces a current AuthenticationStatus (Token { last_valid_token, last_error? } or Unauthorized). The runtime library injects Authorization: Bearer <jwt> (REST) or authorization metadata (gRPC) on every call, and pushes a Reauthenticate envelope on long-lived ingest/outlet streams when the token rotates.
  • Logging: each runtime library accepts a logging facade so you can plug your application's logger in.

Per-language guides