Skip to main content
Glama
Inistate MCP Server

Inistate MCP Server

Official
by Inistate

Inistate MCP Server

MCP server for the Inistate platform — module discovery, entry management, and activity submission.

Setup

Environment Variables

Variable

Required

Default

Description

INISTATE_API_TOKEN

Yes

—

Bearer token for Inistate API authentication

INISTATE_API_BASE

No

https://api.inistate.com

API base URL

INISTATE_MCP_MODE

No

configure

Initial mode: runtime, configure, or frontend (see Modes)

INISTATE_MCP_NO_SETUP

No

—

Set to 1 to force server mode from a terminal (skip the interactive wizard)

INISTATE_DEBUG_FILE

No

—

Set to 1 to log write-path tool calls to ./debug.log, or to a path to log there. Off by default; logs identifiers only, never field values

No clone or build needed — npx will fetch and run the published package on demand:

npx -y inistate-mcp

Or install globally:

npm install -g inistate-mcp
inistate-mcp

Run the binary in a terminal with no MCP client attached and it walks you through entering your API token and picks the right config file for your client:

npx -y inistate-mcp
# or, explicitly:
npx -y inistate-mcp setup

Supported clients: Claude Desktop, Claude Code (global or project-local .mcp.json), Cursor, Windsurf, Codex CLI, VS Code (user profile or workspace .vscode/mcp.json), Cline, Gemini CLI (global or workspace). Pick "Print config only" to get a JSON block to paste anywhere else.

The wizard only runs when stdin is a TTY (i.e., you launched it yourself). When an MCP client spawns the binary via piped stdio, it skips the wizard and runs as a normal MCP server — set INISTATE_MCP_NO_SETUP=1 if you need to force server mode from a terminal.

Claude Desktop Configuration

Add to your claude_desktop_config.json:

{
  "mcpServers": {
    "inistate": {
      "command": "npx",
      "args": ["-y", "inistate-mcp"],
      "env": {
        "INISTATE_API_TOKEN": "your-token-here"
      }
    }
  }
}

Claude Code Configuration

claude mcp add inistate -e INISTATE_API_TOKEN=your-token-here -- npx -y inistate-mcp

Install from source

git clone https://github.com/Inistate/inistate-mcp.git
cd inistate-mcp
npm install
npm run build

Then point your MCP client at node /absolute/path/to/inistate-mcp/build/index.js.

Related MCP server: ResearchTwin MCP Server

Tools

Tools marked (configure) are only exposed in configure mode — see Modes. Tools that depend on a local-runtime capability, such as scaffold_module, are not exposed by the hosted Platform.

Tool

Description

list_workspaces

List workspaces the user has access to

set_workspace

Set the active workspace

list_modules

List all discoverable modules in the workspace

get_module_schema

Get the canvas schema (basic or extended tier) — available in every mode

get_module_canvas

Get full module definition with stable IDs (round-trippable) (configure)

list_entries

Query entries with filters, sorting, and pagination

aggregate_entries

Count, sum, average, min or max over matching entries, optionally grouped — the platform does the arithmetic

get_entry

Read a single entry by ID

get_form

Get form fields and defaults for an activity

submit_activity

Create, edit, delete, or run custom activities

submit_activities

Bulk variant — same activity applied to up to 100 entries in one call

get_entry_history

Get entry audit trail and comments

request_upload_url

Default upload path — get a presigned S3 URL to PUT file bytes to

confirm_upload

Confirm a presigned upload completed; returns the File/Image field path

upload_file

Fallback upload via base64/multipart (use only if the presigned flow fails)

download_file

Download a file (returns pre-signed URL)

design_workflow

Generate a scaffolded module template from a description (configure)

validate_design

Validate a module schema before creating or updating (configure)

create_module

Create a new module with schema (configure)

update_module

Update an existing module's schema (configure)

scaffold_module

Draft a module schema from existing SQLite, Notion, or Airtable data (configure) — local runtime (inistate-core) only; it never creates a module

switch_mode

Switch the active mode (runtime / configure / frontend)

Resources

URI

Description

inistate://modules

List all modules

inistate://modules/{name}/canvas

Basic module schema (fields + states)

inistate://modules/{name}/canvas/extended

Extended schema with activities and flows

inistate://guardrails

Server-enforced submit_activity rules (read once per session)

inistate://schema/runtime

Runtime schema — entry/activity/file types and filter operators (default)

inistate://schema/configure

Module-design schema — write format, field types, colors (configure)

inistate://design-guide

FACTS Module Design Guide (configure)

inistate://frontend-guide

REST API reference for hand-written UIs (frontend)

Prompts

Prompt

Description

design_factsops_workflow

Guide an agent through designing a complete workflow module (configure)

execute_activity

Guide an agent through executing a specific activity

diagnose_entry

Guide an agent through investigating an entry's state and history

modify_module

Guide an agent through modifying an existing module's schema (configure)

Modes

The server exposes a focused tool/resource surface depending on the active mode, keeping agent context lean. Use switch_mode to change it, or set the initial mode via the INISTATE_MCP_MODE env var (default: configure).

Mode

Surface

runtime

Entry and activity operations only — querying, reading, submitting, files, history. The leanest surface for using existing modules.

configure

Everything in runtime plus the module-design tools, resources, and prompts (marked (configure) above).

frontend

Everything in configure plus the inistate://frontend-guide resource for building hand-written UIs against the REST API.

Tools and resources marked (configure) / (frontend) are absent from the tool list in narrower modes — switch modes to reveal them.

Typical Workflow

  1. list_workspaces → set_workspace — select a workspace (auto-selected when exactly one matches; both return the workspace's module list, so list_modules is only needed to refresh)

  2. get_module_schema — understand a module's fields, states, and activities

  3. get_form — discover required fields before the first submission per (module, activity); reuse its schema for further entries

  4. submit_activity — create or update entries (submit_activities for bulk)

  5. list_entries — query and browse data (use the fields parameter to keep payloads small)

  6. get_entry_history — review entry history

Development

npm run watch          # Watch mode for TypeScript compilation
npm run inspector      # Test with MCP Inspector

Branches

  • main is the development branch. Feature and fix work lands here.

  • production is the publishing branch. It only receives release merges.

Packaging & Versioning

Every change that should ship needs a changeset:

# After coding, on a feature branch merged into main
npx changeset

# Choose the bump (patch / minor / major) and describe the change

Releasing

Releases run from main. A release is a v* tag on production; pushing the tag runs the Publish GitHub Actions workflow (.github/workflows/publish.yml), which publishes to npm and the MCP registry.

npm run release              # full release
npm run release -- --no-push # do everything locally, push nothing
npm run package:chatgpt      # create the ChatGPT plugin ZIP in artifacts/

This does:

  1. Checks you are on an up-to-date main with a pending changeset

  2. Runs tests and the build

  3. Bumps the version, updates the changelog and syncs server.json

  4. Commits Release vX.Y.Z on main, merges main into production and tags vX.Y.Z

  5. Pushes main, production and the tag

The workflow fails if the tag, package.json and server.json versions disagree, or if the tagged commit is not on production. It skips the npm publish when that version is already on npm.

Setup the workflow relies on (one time):

  • npm: add a Trusted Publisher for this package (GitHub Actions, repo Inistate/inistate-mcp, workflow publish.yml)

  • MCP registry: the workflow logs in with GitHub OIDC, so no personal login is needed

Publishing manually (fallback)

Only if the workflow is unavailable. Install mcp-publisher:

curl -L "https://github.com/modelcontextprotocol/registry/releases/latest/download/mcp-publisher_$(uname -s | tr '[:upper:]' '[:lower:]')_$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/').tar.gz" | tar xz mcp-publisher && sudo mv mcp-publisher /usr/local/bin/
$arch = if ([System.Runtime.InteropServices.RuntimeInformation]::ProcessArchitecture -eq "Arm64") { "arm64" } else { "amd64" }; Invoke-WebRequest -Uri "https://github.com/modelcontextprotocol/registry/releases/latest/download/mcp-publisher_windows_$arch.tar.gz" -OutFile "mcp-publisher.tar.gz"; tar xf mcp-publisher.tar.gz mcp-publisher.exe; rm mcp-publisher.tar.gz

Then, from the released commit:

npm publish
mcp-publisher validate
mcp-publisher login github   # needs a public Inistate org membership
mcp-publisher publish

Deployment

Deployment is done by hand; there is no CI deploy. After a release, update the server (see PM2 below): pull production, npm ci, npm run build, then npm run pm2:restart.

PM2 (Ubuntu/AWS)

Run the HTTP transport in production using PM2:

npm install
npm run build
npm run pm2:start
npx pm2 save

Enable startup on reboot:

sudo npx pm2 startup systemd -u ubuntu --hp /home/ubuntu
npx pm2 save

Common operations:

npm run pm2:restart
npm run pm2:logs
npm run pm2:stop

Set required environment variables (INISTATE_API_TOKEN, and optionally INISTATE_API_BASE, INISTATE_WORKSPACE_ID, OAUTH_ISSUER_URL, INISTATE_APP_URL) in your shell, PM2 ecosystem env, or deployment secret manager before starting.

Testing

Run all tests

npm test

Watch mode (re-runs on file changes)

npm run test:watch

Test structure

Tests are in src/ alongside the source files and use Vitest:

File

Type

What it covers

src/schema.test.ts

Unit tests (76)

designWorkflow, validateDesign (including platform parity and input normalization), helper functions (isValidFieldType, isValidColor, isValidActor, suggestColorForState)

src/activity-guard.test.ts

Unit tests (42)

submit_activity guard rules — human/hybrid actor, state-change confirmation, confidence-inflation, reference-shape validation

src/tools.schema.test.ts

Unit tests (19)

Tool input-schema shapes and validation

src/backend-capabilities.test.ts

Unit tests (9)

Capability gating — tools the active backend cannot serve return a capability message

src/flagged-annotation.test.ts

Integration tests (5)

Flagged-response annotation — suppressed transitions are explained (flag_reason + agent_action) so agents stop retrying with higher confidence

src/server.test.ts

Integration tests (17)

Spins up the MCP server as a child process and exercises it through the official MCP SDK client — mode-gated tool/resource/prompt discovery, switch_mode, resource reads, prompt retrieval, and local tool calls

Unit tests cover:

  • Field type and color validation against the schema

  • State color suggestion logic

  • Design validation: duplicate names, invalid types/colors/actors, initial state rules, flow integrity, unreachable states, unused activities, AI confidence warnings

  • Input normalization: field-type, state-color, and industry aliases; parsing states from a description

  • Workflow design: pattern detection (approval, ticket, pipeline, record list), industry defaults

Integration tests verify (no API token needed):

  • Mode-gated tool/resource/prompt discovery — runtime mode hides the configure surface, switch_mode reveals and collapses it

  • design_workflow, validate_design work end-to-end through the MCP protocol

  • Static resources (inistate://schema/runtime, inistate://design-guide) return valid content

  • All 4 prompts return correctly templated messages

Interactive testing with MCP Inspector

INISTATE_API_TOKEN=your-token npm run inspector

Opens a browser UI where you can interactively call tools, inspect schemas, and see responses.

Available Tools

21 tools
aggregate_entriesAggregate EntriesA
Read-onlyIdempotent
Inspect

Totals without paging rows: count, sum, average (ave), min or max of a field over the entries list_entries would list, optionally grouped by a field (a date by day, week or month) and broken down by a second field. Use it for 'how many / how much / total / average / top N / per month' questions instead of adding up list_entries pages.

The query parameters (module, listing, state, search, filters) ARE list_entries' — same names, same meaning, same access — so pass exactly what you would pass list_entries to read those entries.

The answer: groups [{key, count, value}] (with a breakdown, values [{key, value}] per group), total {count, value} over EVERY matching entry, complete (false: the module's engine read only its first 501 entries, so the figures are partial — narrow the filters, or say they are partial) and groupsTruncated (only the largest top groups, or the latest periods, are listed; total is still whole).

Filter or group by state when Cancelled or Draft entries must not count. What a figure means — signs, which entries belong in it — comes from the module's description and get_module_schema.

Inputs: op (required), module (required), top, field, +8 more.

confirm_uploadConfirm UploadAInspect

Confirm a presigned upload after the PUT to uploadUrl succeeded. The server verifies the object in S3 and returns { url, filename, mimeType, size } — url is the /s/ path usable as a File/Image field value. Returns 400 if the file is not in S3 (ensure the PUT completed first).

Inputs: s3Key (required), workspaceId.

create_moduleCreate ModuleAInspect

Create a new module. Supports workflow modules (states, activities, flows) and record list modules (fields only). Requires Administrator, Consultant, or Workspace Admin role. Validates internally with the same rules as validate_design and returns structured errors without creating anything — a separate validate_design call beforehand is optional. See inistate://schema/configure for field types, color palette, and design rules.

Inputs: name (required), card, icon, flows, +5 more.

design_workflowDesign WorkflowA
Read-onlyIdempotent
Inspect

Generate a scaffolded ModuleSchema template from a natural language description. Use when the user wants to create a new module or workflow.

Design workflow: design_workflow → (complete template) → validate_design → create_module → get_module_schema(tier=extended). Load resources inistate://schema and inistate://design-guide before designing for valid field types, colors, and design rules.

Inputs: description (required), industry.

download_fileDownload FileA
Read-onlyIdempotent
Inspect

Download a file by module name. Construct the URL from a File/Image field value: field.path = '/s/{guid}/{fileName}'. Returns a pre-signed S3 URL (1hr TTL).

Inputs: guid (required), fileName (required), moduleName (required), workspaceId.

get_entryGet EntryA
Read-onlyIdempotent
Inspect

Read-only lookup of a single entry by its ID; it changes nothing and performs no activity. Returns current field values, state, audit metadata, and the names of the activities available on it (to perform one, use get_form then submit_activity).

Inputs: module (required), entryId (required), workspaceId.

get_entry_historyGet Entry HistoryA
Read-onlyIdempotent
Inspect

Get the audit trail and comments for an entry. Returns chronological list of actions (create, edit, state changes, comments) with field-level change details and AI traceability context.

Inputs: module (required), entryId (required), page, workspaceId.

get_formGet Activity FormA
Read-onlyIdempotent
Inspect

Read-only lookup of the input form for one named activity of one module; it does not perform the activity (submit_activity does). Returns the form fields, current values, and options. Call this before the FIRST submit_activity on each (module, activity) pair — the form schema is stable within a session, so reuse it for subsequent entries (per-entry current values come from get_entry/list_entries). User values with no matching field: omit them and note the omission. Never fabricate form data — when a value is uncertain, submit with a lower ai.confidence and state the assumption instead of blocking to ask. A field may carry label: the name THIS activity's form shows for it (the designer relabelled it) — when the user names a field by that label, it means this field; key input by the field name (the label is accepted too). The response's actor says who may perform the activity: ai — submit it; hybrid — show the user what you plan to submit and get their explicit approval, then submit with confirmed: true; human — do not submit, a person performs it in Inistate. The response's ai_hint/ai_instruction are the designer's guidance for performing the activity; an ai_hint on a field or Table/List column says how to fill it.

Inputs: module (required), entryId, activity, workspaceId.

get_module_canvasGet Module CanvasA
Read-onlyIdempotent
Inspect

Get the full module definition with stable IDs. The output is round-trippable — modify and send back via update_module. Use this when modifying a module to preserve IDs for renaming.

Modify workflow: list_modules → get_module_canvas → (apply changes) → validate_design → update_module. Load resource inistate://schema before modifying to know valid field types, colors, and actors.

Inputs: module (required), workspaceId.

get_module_schemaGet Module SchemaA
Read-onlyIdempotent
Inspect

Read-only lookup of one module's schema; it changes nothing and performs no activity. Returns the canvas schema for a module. Use tier=basic (default) for fields and states only. Use tier=extended to also include activities and flows. Use basic for query operations. Use extended when you need to understand available activities and state transitions.

What the module's designer wrote for an AI rides beside the name lists: stateDetails (both tiers) gives each state's ai_hint/ai_instruction — e.g. which states no longer count — and activityDetails (extended) gives each activity's actor (ai: you may submit it; hybrid: only after the user approves the planned submission; human: never — a person performs it), ai_hint/ai_instruction, confidence_threshold and from (the states it can be performed in). A top-level ai_instruction is the module's standing instruction — follow it.

Both tiers include your accessible listings: each carries its designed filter in the SAME shape as list_entries' filters (applied automatically when that listing is queried — pick the listing whose conditions already match the question and do NOT re-add them as filters), plus partialFilter (an inexpressible formula/script condition also applies), profileOnly (rows limited to the current user's own entries) and scripted markers. Pass a listing's name as list_entries' listing.

Inputs: module (required), tier, workspaceId.

list_entriesList EntriesA
Read-onlyIdempotent
Inspect

Query entries with filters, sorting, pagination. Filter keys are field display names; values are equality (simple) or operator objects (contains/startsWith/endsWith/min/max/above/below/between/after/before/empty/exists/yes/no/is/not/excludes). Use {or:[…]} for OR; multiple keys are AND-ed. Use 'me' for User-field self-match. See FilterOperators in inistate://schema/runtime for the full set.

Access: non-admin users cannot query the unfiltered default 'Everything' view on modules that have listings — pass listing with one of their accessible listings (an access-denied response names them).

Token control: use fields to restrict the returned data to just the columns you need. For modules with many fields this can shrink the response by an order of magnitude. Every item carries entryId, documentId and state whatever fields holds; the other system fields (date, createdBy, createdDate, updatedBy, updatedDate, assignees, due) come with the full row, but when fields is given only if it names them.

Check each item's state before totalling, counting or ranking entries: a Cancelled or Draft entry usually must not count. get_module_schema's stateDetails says what each state means.

Inputs: module (required), state, fields, search, +7 more.

list_modulesList ModulesA
Read-onlyIdempotent
Inspect

List all discoverable modules in the current workspace. set_workspace already returns this list — call this only to refresh it or when operating stateless without set_workspace.

Inputs: workspaceId.

list_workspacesList WorkspacesA
Read-onlyIdempotent
Inspect

List workspaces the current user has access to. Typically the first call of a session. If exactly one workspace matches, it is selected automatically and its module list is returned — no set_workspace or list_modules needed; otherwise call set_workspace next. Administrators: without search this lists your own memberships; pass search to find any workspace by name.

Inputs: search.

request_upload_urlRequest Upload URLAInspect

DEFAULT upload path for every file (up to 500MB); upload_file is only the fallback if this flow fails. Flow: 1) call this tool, 2) PUT the raw bytes to uploadUrl with Content-Type exactly matching contentType (S3 rejects mismatches with 403), 3) call confirm_upload({ s3Key }) — its returned path is the File/Image field value for submit_activity. uploadUrl expires in ~1 hour; call again on expiry.

Inputs: module (required), fileName (required), fileSize (required), contentType, +1 more.

set_workspaceSet Active WorkspaceA
Idempotent
Inspect

Set the active workspace for the current session. The response includes the workspace's module list — go straight to list_entries / get_form / get_module_schema with those names; list_modules is only needed to refresh. In stateless/remote mode, prefer passing workspaceId directly to each tool instead.

Workflow sequences after workspace is set:

  • Design: design_workflow → create_module (validates internally)

  • Execute: list_entries → get_form → submit_activity

  • Modify: get_module_canvas → validate_design → update_module

  • Query: list_entries → get_entry / get_entry_history; aggregate_entries for totals

Inputs: workspaceId (required).

submit_activitiesSubmit Activities (Bulk)A
Destructive
Inspect

Write operation, the bulk variant of submit_activity: one call applies one named activity of one module to many entries (the same activity for every item; nothing else runs), each item with its own input. Use instead of N sequential submit_activity calls when creating/editing many rows — one tool turn instead of N. A per-item ai wholly replaces the top-level default (no partial merge). Items run sequentially fail-soft on the server: one failure does not abort the rest; per-item outcomes (success, entryId, flagged, validation details) return in results — use clientRef to correlate. Max 100 items; chunk beyond that. Guardrails match submit_activity at batch level: actor='human' rejects the whole batch; actor='hybrid', activity='changeStatus', or any state override (top-level or per-item) requires confirmed: true.

Inputs: ai (required), items (required), module (required), activity, +2 more.

submit_activitySubmit ActivityA
Destructive
Inspect

Write operation: one call performs exactly one named activity on one entry of one module, and nothing else runs. The activity is the activity argument — a standard one (create [no entryId], edit, delete, changeStatus, comment, duplicate, manage) or a custom activity the workspace's designer defined (listed by get_module_schema tier=extended); activity names are data, not hidden tools. Call get_form before the first submission per (module, activity); reuse its schema for further entries. The ai object is REQUIRED (reasoning + model + confidence). If confidence < the activity's threshold, the transition is suppressed and the entry is flagged. Server-side guard rules (human/hybrid actor, state-change confirm, confidence-inflation) may block — see inistate://guardrails. Input shapes: ActivitySubmission in inistate://schema/runtime.

Inputs: ai (required), module (required), due, input, +8 more.

switch_modeA
Idempotent
Inspect

Switch tool surface. 'configure' (default) = entry CRUD + module design tools and design resources. 'runtime' = entry CRUD plus get_module_schema (available in every mode). 'frontend' = configure + the inistate://frontend-guide resource (REST reference for building Vue/React UIs that call the Inistate API directly) — use it when the user wants a custom UI. The tool/resource list refreshes via list_changed after this call.

Inputs: mode (required).

update_moduleUpdate ModuleA
DestructiveIdempotent
Inspect

Update an existing module. A section you pass (information/states/activities/flows) replaces that section's entire list — include every existing item you want to keep (matched by id, which enables renaming; omit id to add new items). Omitted sections are left unchanged. Always call get_module_canvas first to obtain the stable module id and item ids. Full-canvas payloads (information included) are validated internally like create_module; for partial payloads, validate the merged canvas with validate_design first.

Inputs: id (required), card, icon, name, +6 more.

upload_fileUpload File (Fallback)AInspect

FALLBACK ONLY — use request_upload_url + confirm_upload first; call this only after that presigned flow has actually failed. Uploads via base64. Returns { path, filename, mimeType, size } — use path as the File/Image field value in submit_activity. Max 50MB. Blocked: .exe, .bat, .cmd, .dll, .msi.

Inputs: file (required), name (required), module (required), mimeType, +1 more.

validate_designValidate DesignA
Read-onlyIdempotent
Inspect

Validate a module schema without submitting anything. create_module (and update_module on full-canvas payloads) runs these same checks internally, so this tool is optional there — use it to iterate on a draft, or before a partial update_module where the merged canvas cannot be checked client-side.

Inputs: schema (required), mode, workspaceId.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A4.2/5.0

    Scored across 21 tools

    Disambiguation4/5

    Most tools target clearly distinct resources/actions, and overlapping pairs like submit_activity vs submit_activities (single vs bulk) and upload_file vs request_upload_url/confirm_upload (fallback vs default flow) are explicitly distinguished in their descriptions. The only mild confusions are the three read-lookup tools (get_form, get_module_schema, get_module_canvas) which are close in purpose, though descriptions do clarify. On the whole an agent can reliably pick the right tool.

    Naming Consistency5/5

    All 21 tool names are snake_case and follow a verb_noun pattern (validate_design, get_module_canvas, list_entries, create_module, submit_activity, request_upload_url, confirm_upload, switch_mode, etc.). No camelCase mixing or stylistic outliers — highly predictable naming throughout.

    Tool Count3/5

    21 tools sits in the heavy band and spans several sub-domains (workspace, module design, entry CRUD, aggregation, file upload/download). Given the multi-mode platform scope it is defensible, but it is toward the upper end and a few clusters (three upload tools, three module-read tools) could be tightened.

    Completeness4/5

    Coverage is strong: workspace select/list, module create/update/validate/design, entry list/get/history/aggregate/form, single and bulk activity submission, and a full presigned upload plus download flow. Entry deletion is handled via the submit_activity 'delete' activity, so the main gap is a lack of module deletion/lifecycle removal, which is a minor omission.

    Maintenance

    ActivityNo data
    ResponsivenessSyncing

    Related MCP Connectors

    Related MCP Servers