Tacit MCP
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| TACIT_API_KEY | Yes | Your Tacit API key | |
| TACIT_API_URL | No | API base URL (for self-hosted deployments) | https://app.betacit.com |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": true
} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| tacit_list_sitesA | List all building sites the current API key has access to. Each site represents a physical location (building, campus, warehouse) managed in Tacit. Sites are the top-level container. You need a site ID to query buildings, equipment, points, zones, and systems. Returns: Array of sites with id, name, address, city, country, timezone. Use this tool first to discover available sites before querying building data. |
| tacit_graphqlA | Execute a GraphQL query against the Tacit building digital twin API. Compose any query using the Brick-compliant schema. Supports nested fields, filtering by Brick class, supply chain traversal (upstream/downstream), and recursive location hierarchy. Use tacit_list_sites first to get a valid site ID, then construct queries freely. Args:
Tacit GraphQL Schema - Brick-compliant Building APIRoot QueriesAll root queries require siteId (get from tacit_list_sites). building(siteId!, id, name, nameMatch) → [Building] equipment(siteId!, id, name, nameMatch, locationId, locationName, systemId, is, hasProperty, propertyValue) → [Equipment] point(siteId!, id, name, nameMatch, equipmentId, locationId, locationName, zoneId, systemId, is, equipmentIs, hasProperty, propertyValue) → [Point] zone(siteId!, id, name, nameMatch, locationId, is, hasProperty, propertyValue) → [Zone] system(siteId!, name, nameMatch, is, hasProperty, propertyValue) → [System] location(siteId!, locationId!) → Location entityByIfcId(siteId!, ifcId!) → KgEntity (union: Building | Location | Zone | System | Equipment) Types and FieldsBuilding { uri, id, name, type, ifcId, properties { name value unit } locations(name, nameMatch, is, recursive) → [Location] zones(name, nameMatch, is, recursive) → [Zone] systems(name, nameMatch, is, recursive) → [System] equipment(name, nameMatch, is, recursive) → [Equipment] points(name, nameMatch, is, recursive) → [Point] } Equipment { uri, id, name, type, typeHierarchy, ifcId, properties { name value unit } points(name, nameMatch, is) → [Point] # sensors/actuators on this equipment parts(name, nameMatch, is) → [Equipment] # sub-components partOf → Equipment # parent equipment feeds(name, nameMatch, is) → [Equipment] # what this equipment feeds fedBy(name, nameMatch, is) → [Equipment] # what feeds this equipment upstream(maxDepth, medium, is) → [Equipment] # full upstream chain downstream(maxDepth, medium, is) → [Equipment] # full downstream chain location → Location systems → [System] } Point { uri, id, name, type, typeHierarchy, unit, equipmentId, timeseriesId currentValue { value timestamp quality } # latest live reading (null if no data) properties { name value unit } equipment → Equipment location → Location } Zone { uri, id, name, type, typeHierarchy, ifcId, properties { name value unit } points(name, nameMatch, is) → [Point] fedBy(name, nameMatch, is) → [Equipment] # equipment feeding this zone upstream(maxDepth, medium, is) → [Equipment] locations → [Location] } System { uri, id, name, type, ifcId, properties { name value unit } equipment(name, nameMatch, is, recursive) → [Equipment] points(name, nameMatch, is, recursive) → [Point] } Location { uri, id, name, type, ifcId, properties { name value unit } locations(name, nameMatch, is, recursive) → [Location] # child locations parent → Location equipment(name, nameMatch, is, recursive) → [Equipment] points(name, nameMatch, is, recursive) → [Point] zones → [Zone] } EnumsNameMatch: CONTAINS | EXACT (default: CONTAINS) Filter Parameter Guide
Example QueriesList AHUs with their sensor points{ equipment(siteId: "x", is: "AHU") { name type points { name type unit timeseriesId } } } Trace what feeds a zone{ zone(siteId: "x", name: "Atrium") { name upstream(maxDepth: 3) { name type } } } Building floor hierarchy with equipment{ building(siteId: "x") { name locations(recursive: true) { name type equipment { name type } } } } Equipment detail with parts and supply chain{ equipment(siteId: "x", name: "AHU-001") { name type parts { name type } feeds { name type } fedBy { name type } points { name type unit timeseriesId } } } All temperature sensors with current values{ point(siteId: "x", is: "Temperature_Sensor") { name unit timeseriesId currentValue { value timestamp } equipment { name type } location { name } } } Points on VAVs in a specific location{ point(siteId: "x", locationName: "Tower West", equipmentIs: "VAV") { name type unit timeseriesId equipment { name } } } Look up an entity by its IFC Global ID{ entityByIfcId(siteId: "x", ifcId: "3Zu5Bv0LOHrPC6") { ... on Equipment { name type points { name } } ... on Location { name type } } } |
| tacit_timeseriesA | Query historical or live sensor data for one or more points. Points are identified by their timeseriesId (UUID). Use tacit_graphql first to find points and their timeseriesId values. Args:
Common patterns:
For current/live values, use tacit_graphql with the currentValue { value timestamp quality } field on Point instead of this tool. Returns: Array of series, each with timeseriesId, name, type, unit, equipment, and data records [{t, v}]. |
| tacit_list_filesA | List documents and files associated with a site. Returns metadata for files uploaded to a site: spec sheets, maintenance documents, BIM source files, 3D models, and knowledge graph data. Useful for answering questions like "What documentation exists for this building?" or "Are there spec sheets for this equipment?" Args:
Returns: List of files with name, category, size, and upload date. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 4 tools
Each tool has a distinct and non-overlapping purpose: tacit_list_sites lists sites, tacit_graphql queries building data, tacit_timeseries retrieves sensor data, and tacit_list_files lists documents. The descriptions clearly differentiate their functions, with no ambiguity in tool selection.
All tool names follow a consistent 'tactic_' prefix with descriptive snake_case suffixes (e.g., tacit_list_sites, tacit_graphql). This pattern is uniform across all four tools, making them predictable and easy to identify.
With 4 tools, the server is well-scoped for its purpose of interacting with building digital twin data. Each tool serves a critical role: site discovery, data querying, timeseries retrieval, and file listing, providing a complete workflow without unnecessary complexity.
The tool set covers core operations for building data access: listing sites, querying entities, retrieving timeseries, and listing files. Minor gaps exist, such as no explicit tools for creating or updating data, but the GraphQL tool allows flexible queries that can handle many needs, making it reasonably complete for query-focused workflows.