flowIQ for developers

flowIQ maps how teams actually work: captures (recorded walkthroughs and interviews) become step-by-step workflows, and multiple captures of the same process get synthesized into one process map. this page documents the hosted mcp server that lets ai agents read and act on that data.

hierarchy: workspace (organization) > teams > processes > captures.

getting started

  1. sign in at app.simplestuff.ai and open settings > api keys (click your name in the sidebar, then workspace settings).
  2. create a key. it starts with fiq_ and is shown once - store it somewhere safe. we only keep a hash.
  3. connect an mcp client (below) or call the endpoint directly over json-rpc.
# quickest check: list the tools your key can call
curl -X POST https://app.simplestuff.ai/api/mcp \
  -H "Authorization: Bearer fiq_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'

authentication

every request needs an api key, sent as Authorization: Bearer fiq_... or X-API-Key: fiq_.... keys are user-wide: one key works across every workspace you are a member of, and each call can target a workspace via the workspace_id parameter.

  • up to 10 active keys per user.
  • revoking a key (settings > api keys) disables it immediately.
  • keys inherit your permissions - nothing more. a key can never see workspaces you are not a member of.
treat keys like passwords. if one leaks, revoke it in settings and mint a new one - the raw key is never stored on our side, so there is nothing to rotate server-side.

connect a client

the mcp server lives at https://app.simplestuff.ai/api/mcp (streamable http, stateless - no session handshake required).

claude code

claude mcp add flowiq --transport http https://app.simplestuff.ai/api/mcp \
  --header "Authorization: Bearer fiq_YOUR_KEY"

claude desktop / other json config clients

{
  "mcpServers": {
    "flowiq": {
      "type": "http",
      "url": "https://app.simplestuff.ai/api/mcp",
      "headers": {
        "Authorization": "Bearer fiq_YOUR_KEY"
      }
    }
  }
}

cursor

// .cursor/mcp.json
{
  "mcpServers": {
    "flowiq": {
      "url": "https://app.simplestuff.ai/api/mcp",
      "headers": { "Authorization": "Bearer fiq_YOUR_KEY" }
    }
  }
}

github copilot (vs code)

vs code uses a servers key (not mcpServers) and can prompt for the key instead of storing it in the file:

// .vscode/mcp.json
{
  "inputs": [
    {
      "id": "flowiq-key",
      "type": "promptString",
      "description": "flowIQ api key (fiq_...)",
      "password": true
    }
  ],
  "servers": {
    "flowiq": {
      "type": "http",
      "url": "https://app.simplestuff.ai/api/mcp",
      "headers": { "Authorization": "Bearer ${input:flowiq-key}" }
    }
  }
}

then open copilot chat in agent mode, click the tools icon, and enable the flowiq tools. vs code prompts for the key on first start and stores it encrypted. on github.com, copilot coding agent takes the same server config under repository settings > copilot > coding agent > mcp configuration (store the key as a copilot environment secret, not in the json).

microsoft copilot (copilot studio)

microsoft 365 copilot reaches mcp servers through a copilot studio agent - there is no json file; the server is added in the ui:

  1. in copilot studio, open your agent and go to tools > add a tool > new tool > model context protocol.
  2. server name flowiq, server url https://app.simplestuff.ai/api/mcp, and a short description (the orchestrator uses it to decide when to call the server - e.g. "reads and manages flowIQ process maps, captures and syntheses").
  3. authentication: api key, type header, header name X-API-Key.
  4. select create, then create a new connection and paste your fiq_ key as the api key value.
  5. add to agent - the 30 tools appear on the agent's tools page. publish the agent to make it available in microsoft 365 copilot or teams.

copilot studio requires streamable http transport (sse is not supported) - our endpoint is streamable http, so no adapter is needed. note that power platform data policies apply: if your tenant regulates connectors, they also gate this mcp connection.

how scoping works

keys are user-wide, so the workspace is chosen per call. tools that operate at workspace level take an optional workspace_id:

  • omit it and the call uses your first workspace - fine if you only have one.
  • pass it explicitly when you belong to several. list_workspaces returns the ids.
  • membership is re-validated on every call. a workspace_id, process or capture you cannot access answers not_found - existence is never revealed across workspaces.

recommended flow for agents:

  1. list_workspaces to see the options.
  2. list_teams / list_processes to find the process.
  3. list_captures + get_capture for recorded detail, get_synthesis for the merged process-level view.

tool reference

30 tools. reads mirror what a member sees in the app; writes are real and follow the same permission rules as the ui.

list_workspacesread

every workspace (organization) this key can act in, with your role in each. call this first; pass the chosen workspace_id to other tools.

params: none

list_teamsread

teams in a workspace. teams group related processes.

params: workspace_id? (uuid)

list_processesread

processes in a workspace, optionally filtered to one team. a process is a mapped piece of how the team works; its captures hold the recorded detail.

params: workspace_id? (uuid), team_id? (uuid)

get_processread

one process: name, team, whether a synthesis exists, and its capture list.

params: process_id (uuid)

list_capturesread

the captures (recorded workflow sessions) of a process.

params: process_id (uuid)

get_captureread

one capture: extracted workflow (steps, exceptions), status, duration, language. transcripts are omitted unless requested - they can be long.

params: capture_id (uuid), include_transcript? (boolean, default false)

get_synthesisread

the process-level synthesis: the merged view built from multiple captures (consensus steps, variations, open questions). fails with no_synthesis if none exists yet.

params: process_id (uuid)

list_membersread

members of a workspace with their names and roles.

params: workspace_id? (uuid)

create_processwrite

create a new process in a team. captures can then be recorded against it.

params: team_id (uuid), name (string, 1-120 chars)

create_teamwrite

create a new team in a workspace. the caller becomes its owner.

params: workspace_id? (uuid), name (string, 1-80 chars)

invite_memberwrite

invite someone to a team by email. new emails get a real invite email; existing accounts are added directly and notified in-app. allowed for a workspace owner/admin or a manager of that team.

params: team_id (uuid), email (string), role? (manager | member, default member)

update_capture_stepswrite

replace the step list of a capture you own. steps are objects with at least step_number and description. owner-only.

params: capture_id (uuid), steps (array of objects, min 1)

finalize_capturewrite

mark a capture as completed (reviewer sign-off) or reopen it. allowed for the capture owner or a manager of its process.

params: capture_id (uuid), finalized (boolean)

delete_capturedestructive

permanently delete a capture you own. irreversible - clients should confirm with the user first.

params: capture_id (uuid)

run_synthesiswrite

start a synthesis run: merges the process’s captures into one process-level view. runs as a background job - poll get_synthesis_status. needs 1+ complete capture with steps, or a text-bearing context file (docs-only reports are labeled as documented, not observed). workspace owner/admin or team manager only. idempotent while a job is live.

params: process_id (uuid), language? (string, default English)

get_synthesis_statusread

the latest synthesis job for a process (pending, running, done, failed). when done, read the result with get_synthesis.

params: process_id (uuid)

get_share_linkread

the public share state of a process; returns the public read-only link when sharing is on. workspace owner/admin or team manager only.

params: process_id (uuid)

set_sharingwrite

turn public sharing of a process on or off. on mints a stable unguessable link (readable by anyone with it, transcripts included); off kills the link. workspace owner/admin or team manager only.

params: process_id (uuid), share (boolean)

export_processread

export a process artifact inline as text: steps.csv (consolidated step register, needs a v2 synthesis), report.json (full synthesis payload), or map.json (process map graph).

params: process_id (uuid), artifact (steps.csv | report.json | map.json)

export_captureread

export a capture artifact inline as text: steps.csv (step table), transcript.txt (speaker-turn transcript), or map.svg (workflow map).

params: capture_id (uuid), artifact (steps.csv | transcript.txt | map.svg)

list_invitationsread

pending invitations of a workspace (email, team, role, sent date). ids feed revoke_invitation.

params: workspace_id? (uuid)

revoke_invitationwrite

revoke a pending invitation so its link stops working. workspace owner/admin only.

params: invitation_id (uuid)

delete_processdestructive

permanently delete a process with all its captures, transcripts, and uploaded files. irreversible - clients should confirm with the user first. workspace owner/admin or team manager only.

params: process_id (uuid)

update_teamwrite

rename a team. workspace owner/admin or a manager of that team only.

params: team_id (uuid), name (string, 1-60 chars)

delete_teamdestructive

delete a team. only works when the team has no processes (fails with team_not_empty otherwise). workspace owner/admin or a manager of that team only.

params: team_id (uuid)

add_team_memberwrite

add an existing workspace member to a team (invite_member handles new people). workspace owner/admin or a manager of that team only.

params: team_id (uuid), user_id (uuid), role? (manager | member, default member)

update_team_memberwrite

change a team member’s team role. cannot target yourself or the team owner. workspace owner/admin or a manager of that team only.

params: team_id (uuid), user_id (uuid), role (manager | member)

remove_team_memberwrite

remove a member from a team (their workspace membership stays). cannot target yourself or the team owner. workspace owner/admin or a manager of that team only.

params: team_id (uuid), user_id (uuid)

update_member_rolewrite

change a member’s workspace role. owner grants/demotions are owner-only; the founding workspace owner cannot be changed; cannot target yourself. workspace owner/admin only.

params: workspace_id? (uuid), user_id (uuid), role (owner | admin | member)

remove_memberdestructive

remove a member from a workspace and all its teams. removing an owner is owner-only; the founding workspace owner cannot be removed; cannot target yourself. workspace owner/admin only.

params: workspace_id? (uuid), user_id (uuid)

rate limits

limitvaluebehavior
calls per key per day1,000resets at midnight utc; over the limit answers http 429
active keys per user10creating an 11th answers http 409
request duration60slong tool calls are cut off at the platform limit

errors

errorwheremeaning
401 invalid_api_keyhttpmissing, malformed, revoked, or unknown key
429 rate_limit_exceededhttpdaily call budget spent; retry after midnight utc
403 forbidden_originhttpbrowser request from an origin we do not allow
*_not_foundtool resultthe resource does not exist or your key cannot access it - deliberately the same answer
no_synthesistool resultthe process has captures but no synthesis has been generated yet
no_evidencetool resultrun_synthesis found nothing to work with - the process needs a complete capture or a text-bearing context file

tool-level failures come back as mcp results with isError: true and a json body like {"error": "process_not_found"} - they are not http errors.