Internal tools and dashboards

Grids, kanban boards, calendars and charts over your entities, branded and shipped to your team without building a frontend.

Last updated

Most teams end up with a pile of spreadsheets: expenses, leads, stock, support requests. They want a proper place to keep that data, filter it, move work along a board and see the numbers. Building an admin interface for it is weeks of work that nobody wants to own.

In Anythink, the Anythink dashboard is that interface. Every entity you create already has a record grid, a kanban board, a calendar and charts. You decide who sees what, put a dashboard on the front page, and brand it as your own. There's no frontend to build or host.

This page is for operations leads, founders and developers building a tool for their own team. It builds an expense tracker as the example. Each step shows the Anythink dashboard, the CLI and an AI assistant (MCP), and links to the guide that covers the detail.

If you haven't used Anythink before, read Core concepts first.

What you'll build#

  • An employees entity and an expenses entity, loaded from a CSV file.
  • Grid, kanban and calendar views of the expenses, with no setup beyond the fields.
  • A Finance role and a focused sidebar menu for it.
  • A dashboard with charts and a table that combines columns from both entities.
  • A workflow that emails the finance team when a new expense is submitted.
  • Your own name, logo and colours.

Step 1: Model the data and import a CSV#

Create the entities, then load your existing spreadsheet. Each view in step 2 depends on the field types you pick here: a select field gives you a kanban board and a date field gives you a calendar.

Entity Field Type Notes
employees name Small text Required. The name field.
employees department Small text, select display Options sales, ops and engineering.
expenses title Small text Required. The name field.
expenses amount Decimal
expenses category Small text, select display Options travel, software and meals.
expenses status Small text, select display Options submitted, approved and rejected. Default submitted.
expenses spent_on Date
expenses employee Many-to-One Points at employees.

An administrator runs the import. Prepare the CSV with a heading row, one record per line, dates as yyyy-MM-dd, and a select field's stored value (approved, not a label):

text
Description,Cost,Type,State,Date
Train to Leeds,84.50,travel,submitted,2026-10-02
Design tool licence,29.00,software,approved,2026-10-03
Team lunch,112.40,meals,submitted,2026-10-05

In the Anythink dashboard

  1. Go to Settings › Data Model and select Add Entity. Create employees, tick Add to Menu if you want it in your sidebar, and add its fields.
  2. Create expenses and add its fields from the table. For each select field, choose the Select display and add the options. For employee, choose Many-to-One and pick employees.
  3. Open the expenses records and select Import, then open New Import.
  4. Drop your .csv file on the upload area. The limit is 50 MB.
  5. Select Auto-Match, fix any headings it missed, and select Run Import. Here Description maps to title, Cost to amount, Type to category, State to status and Date to spent_on.
  6. Follow progress in History. Select View Logs for the log.

With the CLI

bash
anythink entities create employees
anythink fields add employees name --type varchar --required --name-field
anythink fields add employees department --type varchar --display select --options "sales,ops,engineering"

anythink entities create expenses
anythink fields add expenses title --type varchar --required --name-field
anythink fields add expenses amount --type decimal
anythink fields add expenses category --type varchar --display select --options "travel,software,meals"
anythink fields add expenses status --type varchar --display select --options "submitted,approved,rejected" --default submitted
anythink fields add expenses spent_on --type date
anythink fields add expenses employee --type many-to-one --target employees

The CLI has no import command. Upload the file, then start a job with a mapping from each heading to a field:

bash
anythink files upload expenses.csv

anythink fetch /imports/jobs --method POST --body '{
  "entity_name": "expenses",
  "file_id": 4226,
  "mapping_json": "{\"Description\":\"title\",\"Cost\":\"amount\",\"Type\":\"category\",\"State\":\"status\",\"Date\":\"spent_on\"}"
}'

anythink fetch /imports/jobs/2

file_id is the id files upload prints. The last call returns the job's status, processed_records and failed_records.

With an AI assistant (MCP)

text
Create employees with a name and a department select field, and expenses with a title, a decimal amount, select fields for category and status, a spent_on date, and a many-to-one employee field. Then upload expenses.csv and import it into expenses, mapping Description to title, Cost to amount, Type to category, State to status and Date to spent_on. Tell me how many rows failed.

The assistant runs entities create and fields add, then files upload and the import endpoints, through the cli tool. Connect Claude to your backend with MCP sets up the MCP server.

An import only creates records. It never updates existing ones, so importing the same file twice creates every row twice. A row the database rejects is skipped and the rest still load. Records, views and CSV import covers the file rules, saved mappings and what a failed row does. For every field type, see Model your data.

Step 2: Browse the data as a grid, kanban board or calendar#

Open an entity and you get its records in a grid, with five views behind the view switcher: Grid View, Kanban View, Map View, Calendar View and Charts View. You don't configure them. They work from the entity's fields.

View What it needs For expenses
Grid Nothing Sort, filter and edit in place with Instant Edit
Kanban A select field One column per status. Drag a card to approve or reject it
Calendar A date or timestamp field Each expense on its spent_on date

In the Anythink dashboard

  1. Open the expenses entity from the sidebar. Select a column heading to sort. Open a column's menu to filter it.
  2. Select Kanban View, then choose status in the Status Field menu. Drag a card to another column and the record updates at once.
  3. Select Calendar View, and switch between Month, Week, Day and Agenda. Select an event to open its record.

With the CLI

Views live in the dashboard. The CLI works on the records behind them:

bash
anythink data list expenses --filter 'status=submitted' --limit 10
anythink data update expenses 4 --data '{"status":"approved"}'

The second command is what dragging a card to approved does.

With an AI assistant (MCP)

text
Show me the submitted expenses over £100, then mark expense 4 as approved.

The assistant runs data list and data update through the cli tool. Open the entity in the Anythink dashboard and switch to Kanban View or Calendar View to see the result.

The kanban board and calendar load up to 1,000 records. The calendar picks its date field for you from the field names, so call yours start_date and end_date if you need control. The grid remembers your layout, but only in that browser. See Records, views and CSV import for the details.

Step 3: Give each team a focused menu and a role#

A new role starts with access to nothing, and a menu with nothing in it. For each team, create a role that holds only what they need, then a menu for that role. Together they give the finance team a short sidebar with the pages they use.

Permission Why
expenses:read, create, update Work with expenses
employees:read See who submitted an expense
anythink_entities:read, anythink_fields:read Let the Anythink dashboard load each entity and its fields
anythink_dashboards:read Open dashboards

Tick API Access on the role, or the entity permissions don't apply. Leave delete unticked if you want people to reject an expense rather than remove it.

In the Anythink dashboard

  1. Open Settings › Users and select the Roles & Permissions tab. Select +, enter Finance, tick API Access and select Create Role.
  2. Select the role, tick the permissions from the table and select Update Role.
  3. Open Settings, then Menu Configuration, and select Add Menu. Name it Finance and choose the Finance role.
  4. Select the menu, then Add Menu Item. Choose Entity, pick expenses and choose an icon. Do the same for employees.
  5. To add a dashboard to the sidebar, add a Custom Link with the path /dashboard/<id>, using the dashboard's id from your browser's address bar.
  6. Invite people under Settings › Users with the Finance role.

With the CLI

bash
anythink roles create Finance --description "The finance team"
anythink roles list
anythink menus list
anythink menus add-item 12 expenses --icon Receipt
anythink menus add-item 12 employees --icon Users

Replace 12 with the id of the Finance menu, from anythink menus list.

Note: Role permissions are managed in the dashboard. Use the steps above, including to tick API Access. Creating the menu itself is also a dashboard task.

bash
anythink users invite maya@example.com Maya Patel --role-id 104

With an AI assistant (MCP)

text
Create a role called Finance, then add expenses and employees to the Finance menu with the Receipt and Users icons. Invite maya@example.com, Maya Patel, as a Finance user.

The assistant runs roles create, menus add-item and the invitation through the cli tool. Role permissions and creating the menu are dashboard tasks, and the assistant can walk you through them.

When Maya signs in, her sidebar shows Dashboard, Expenses, Employees and Help. Administrators keep the full sidebar.

A menu item is a shortcut, not a permission. Hiding a link doesn't block access, and showing one doesn't grant it, so set up both. See Menu configuration and Roles and permissions. If one team should only see its own records, add row-level security: see Groups and row-level security.

Step 4: Build a dashboard with charts and a materialised view#

A dashboard is a page of widgets. A chart widget counts or sums one entity, grouped by a field or by time. A materialised view widget is a table with a row for each record of one entity and columns that look up matching records in another.

The finance dashboard gets three widgets:

  • A pie chart of expenses by category.
  • A bar chart of total spend per week.
  • A table with a row for each employee, showing whether they have a submitted expense and the amount of their latest one.

In the Anythink dashboard

  1. Open Dashboard in the sidebar. Open the dashboard switcher and select New dashboard. Name it Finance, turn on the share switch so the team can see it, and create it.
  2. Select the pencil, then Add widget and choose Chart. Select Design a new chart.
  3. Pick expenses as the data source and Pie as the chart type. Set the group-by field to category, the aggregate to count, and the timeframe to Last 30 days. Save it.
  4. Add another Chart widget. Choose Bar, set the X axis to spent_on with a week bucket, the aggregate to sum and the Y field to amount.
  5. Select Add widget, choose Materialised view, and name it Employee expenses. Under Show one row per, pick employees.
  6. Select Add column. Set the Source to entity, the Entity to expenses and Match on to employee. Set the Display to exists and add a column filter, status equals submitted.
  7. Add a second column the same way, with the Display set to value, the Value field set to amount and Order set to latest. Check the Preview and save.
  8. Select Save on the dashboard.

With the CLI

Charts are saved through the REST API. Chart request bodies use camelCase names, and responses come back in snake_case.

bash
anythink fetch /charts --method POST --body '{
  "name": "Expenses by category",
  "chartType": "pie",
  "entityName": "expenses",
  "xField": "category",
  "yAgg": "count",
  "timeframePreset": "30d"
}'

anythink fetch /charts --method POST --body '{
  "name": "Spend per week",
  "chartType": "bar",
  "entityName": "expenses",
  "xField": "spent_on",
  "xInterval": "week",
  "yAgg": "sum",
  "yField": "amount",
  "timeframePreset": "90d"
}'

Each response includes the chart's id. Put the charts on a shared dashboard with chart widgets:

bash
anythink fetch /dashboards --method POST --body '{
  "name": "Finance",
  "is_shared": true,
  "widgets": [
    {"type":"chart","title":"Expenses by category","config_json":"{\"chartId\":40}","sort_order":0},
    {"type":"chart","title":"Spend per week","config_json":"{\"chartId\":41}","sort_order":1}
  ]
}'

Materialised views are built in the Anythink dashboard, so add the Employee expenses table there, with the steps above.

With an AI assistant (MCP)

text
Create a pie chart of expenses grouped by category over the last 30 days, and a bar chart of the sum of amount per week over the last 90 days. Then create a shared dashboard called Finance with both charts on it.

The assistant creates the charts and the dashboard through fetch. It can't build a materialised view: add that in the Anythink dashboard. Arranging and resizing widgets is also easier there.

A chart only counts the records its viewer is allowed to read, so with row-level security on, two people can see different numbers on the same dashboard. Charts and views are calculated each time they're opened, so they're always current. For a trend over time use a chart, and for "which of these records have a match elsewhere" use a materialised view. See Dashboards and charts for every chart type, the timeframe and compare settings and sharing, and Materialised views for columns and the TOTAL row.

Step 5: Automate approvals and notifications with a workflow#

A workflow reacts when something happens in your data. When someone submits an expense, you want the finance team to know. The trigger is an Event trigger on expenses, set to run when a record is created. The step is Send An Email, which sends one of your project's email templates.

Before you start: verify a sending domain and create an email template with the type expense_submitted that uses the variables {{ title }} and {{ amount }}. See Send email from a workflow.

In the Anythink dashboard

  1. Open Workflows and select New Workflow. Name it expense-submitted.
  2. Set Event Type to Entity Created and Entity to expenses. Select Create Workflow.
  3. Select Add Step and choose Send An Email. Name it Email finance with the Key send_notice.
  4. Enter finance@example.com as the To Email Address and pick the expense_submitted template.
  5. On the Mappings tab, set title to {{ $anythink.trigger.data.title }} and amount to {{ $anythink.trigger.data.amount }}.
  6. Save the step, make it the start step, save the workflow and select Enable Workflow.

With the CLI

bash
anythink workflows create expense-submitted \
  --trigger Event --event EntityCreated --entity expenses \
  --enabled

anythink workflows step-add <workflow_id> send_notice \
  --name "Email finance" --action SendAnEmail --start --enabled \
  --params '{
    "to": "finance@example.com",
    "template_type": "expense_submitted",
    "payload": "{\"title\":\"{{ $anythink.trigger.data.title }}\",\"amount\":\"{{ $anythink.trigger.data.amount }}\"}"
  }'

payload is a string that holds JSON, so its inner quotes are escaped. Replace <workflow_id> with the id workflows create prints.

With an AI assistant (MCP)

text
Create a workflow called expense-submitted that runs when a record is created in expenses. Add a Send An Email step with the key send_notice that emails finance@example.com using the expense_submitted template, with title and amount filled from the record. Make it the start step and enable the workflow.

The assistant runs workflows create and workflows step-add through the cli tool.

The approval itself is the kanban board from step 2: dragging a card to approved updates status. To tell the submitter, add a second workflow on Entity Updated with a filter of status changed to approved, and the same email step. Test a workflow with Test Workflow in the editor, and read what each step did in its job history. Anythink doesn't retry a failed step, so check Test workflows and read job history if an email doesn't arrive. Triggers, filters, schedules and every step type are covered in How workflows work.

Step 6: Brand it as your own#

Branding is set once, for the whole project, and everyone who signs in to the Anythink dashboard sees it. You set a name and description, two logos, a primary colour, a grey and a corner radius.

In the Anythink dashboard

  1. Open Settings, then Organisation Settings.
  2. In General Settings, set the Name and Description.
  3. In the Branding card, upload a Square Logo and a Standard Logo. Each file can be up to 5 MB. The standard logo shows when the sidebar is open and the square logo when it's collapsed.
  4. Under Theme, choose a Primary Color, a Gray Color and a Corner Radius. The dashboard previews each choice as you click it.
  5. Select Save Changes.

With the CLI

Branding is managed in the Anythink dashboard. Use the steps above. You can choose a name and description when you create a new project:

bash
anythink projects create "Acme Ops" --description "Acme's internal tools" --region lon1

With an AI assistant (MCP)

Branding is managed in the Anythink dashboard, and your assistant can walk you through the steps above.

The project name also appears in the emails your project sends, and your primary colour is used for their heading and button. Dark mode is a personal choice that each person makes for themselves. See Customise the Anythink dashboard.

What you get, and the limits#

What you get

  • A record grid, kanban board, calendar and charts for every entity, with no frontend to build.
  • CSV import, with saved mappings, for loading your existing spreadsheets.
  • A sidebar and a set of permissions for each team, so people only see the pages they need.
  • Dashboards of charts and tables that are always calculated from live data, and that you can share with the team.
  • Workflows that send an email, call another system or update records when something changes.
  • Your own name, logos and colours, applied across the Anythink dashboard.

Limits to plan around

  • Your team uses the Anythink dashboard. It runs at Anythink's address. There's no custom domain for it, and it isn't a bespoke interface. If you need your own screens, build an app on the REST API instead.
  • Branding isn't full white-label. The sidebar always carries a "powered by Anythink" line, and the sign-in pages aren't restyled. There's one theme for the whole project, and only dark mode is personal.
  • Views are fixed. Kanban needs a select field, and the calendar chooses its own date field from your field names. Kanban and calendar load up to 1,000 records, and the map shows the current grid page.
  • Layouts are saved per browser. Column order, widths and the chosen view aren't shared between people or devices.
  • No export in the dashboard. Read records with anythink data list --json --all if you need them out.
  • Import only creates. It never updates or merges, and one-to-many and many-to-many fields can't be mapped.
  • Charts and views have limits. There's no table chart, so use a list widget or a materialised view. A materialised view's count display is a match flag, not a total, and it sorts by a field on its base entity.
  • One default dashboard. The project default is the same for everyone. To send each role somewhere different, put a link to a dashboard in that role's menu.
  • One menu per role, two levels deep. Menu items open pages inside the Anythink dashboard, not external links, and aren't access control.
  • Some tasks are dashboard-only. Role permissions, creating a menu, materialised views and branding are set in the dashboard. The CLI and MCP can create roles and charts, add entity items to a menu, and run workflows.
  • Workflows don't retry. A failed step follows its failure path or ends the job. Runs per month are set by your plan.

Next steps#