https://mcp.metal.ai/mcp. Your AI client discovers these tools automatically after OAuth sign-in. Use this reference when building integrations, debugging tool calls, or understanding what data comes back.
Tool availability depends on the OAuth scopes your connection was granted and on your organization’s settings. Organization settings can hide tools but never widen your scopes. See OAuth scopes.
How tool calls work
Metal implements the Model Context Protocol over streamable HTTP. Your client sends JSON-RPC messages to/mcp; each tools/call request names a tool and passes a JSON arguments object.
Tool discovery and schemas
After OAuth sign-in, your MCP client discovers the exact live tool metadata from the server with the MCPtools/list method. That response is the source of truth for each tool’s description, inputSchema, and safety annotations.
Use this page as the human-readable reference for tool behavior, common parameters, scopes, response shapes, and examples. If you are generating code, validating arguments, or debugging a client integration, inspect the live inputSchema from tools/list instead of hardcoding this page’s parameter tables.
When you inspect a call in a client like Cursor, you typically see:
Response format
Every tool result contains at least one content block. Most calls return a text content block containing JSON;get_document_page is the exception, returning a text block with a caption and citation link plus an image block with the rendered page. Failures return a text block with a plain-text error message.
Successful responses fall into three shapes:
Single record — the JSON object is the payload directly:
data and pagination:
data contains grouped documents and excerpts instead of a flat array:
Errors
When a call fails validation or the backend returns an error, the tool result is marked as an error and the text content holds a message:
Rate-limit errors return structured JSON in the error text:
Pagination
Most list and search tools use page mode (paginationMode: "page"). Pass page (default 1) and pageSize (default 20, max 50). When a tool uses a different default or maximum, its parameter row says so — list_tasks and search_tasks default pageSize to 25 and cap it at 100. Continue while hasMore is true.
get_list_entries and get_score_history use cursor pagination. For get_list_entries, the cursor is pagination.nextToken; for get_score_history, it is metadata.nextToken. Pass the token from the prior response to fetch the next page.
Field definitions for each resource type are available as MCP resources — see Resources below.
OAuth scopes
Tools require OAuth scopes granted during sign-in. Metal enforces these scopes on every tool call for every organization. No organization setting bypasses them. Calling a tool outside your connection’s granted scopes returnsinsufficient scope, naming the missing scope — or, for a tool that accepts any of several scopes, the accepted scopes. To fix it, configure your MCP client to request the missing scope, then disconnect and reconnect so the user can re-consent during a fresh OAuth sign-in. If the sign-in’s authorize step rejects the scope before consent, contact support@metal.ai: scopes are registered per environment by the Metal team, and no setting in your organization enables one.
Companies
Company records returned bysearch_companies, list_companies, get_company, and get_companies include fileCount, the number of linked documents the caller can see for that company. It appears only when the connection has the read:documents scope. An absent fileCount means the count is unknown, either because the connection has no document read access or because the lookup failed. When fileCount is nonzero, pass the company’s ID as companyIds to search_documents or list_documents to work with those documents.
search_companies
Search companies by name. Uses hybrid semantic + keyword matching on company names.
Scope: read:companies
website and linkedinUrl use the resolved observation value when available, with the native company field as a fallback. The remaining discovery fields keep their compact search representation.
list_companies
Browse companies with structured filters only — no text query. Use this for sector, tag, team, or location lists.
Scope: read:companies
Same filter parameters as search_companies except query is not accepted. At least one filter is required.
list_company_tags
List company tags so you can pass exact IDs to tagIds filters.
Scope: read:companies
Returns a paginated list of tag objects with
id, type, and value, plus color and externalReference when set. Match the label against value and pass the tag’s id to tagIds.
get_companies
Retrieve selected resolved fields for exact company IDs. Use this when you already have IDs and need the same fields across many companies without loading each full profile.
Find IDs with search_companies or list_companies. Compact discovery results already return resolved website and linkedinUrl. Use get_company only when you need the full profile, including enrichedValues.
Scope: read:companies
id and canonicalName are always returned and must not appear in fields. relevance is returned only by search_companies and cannot be requested here. A request can contain at most 2,500 ID-field cells. For example, 500 IDs can request up to five fields. The server rejects responses above 512 KiB. Reduce the IDs or fields and retry when a response exceeds that limit.
Observation-backed fields such as website and linkedinUrl use the resolved observation value when available, with the native company field as a fallback. That is the compact equivalent of the values on a full get_company profile.
Use the metal://fields/companies MCP resource to discover standard selectable fields. It includes public native company fields (except relevance) and registered company observation fields. Use get_custom_field_definitions for organization-defined fields:
- Request schema custom fields as
custom.<key>, such ascustom.ideaPriorityStr. - Request custom financial metrics with their existing
custom:<key>names, such ascustom:arr. - Do not request the complete
custom,enrichedValues, ormetricCustommaps.
values; absent or unresolved values are null. Nonexistent or inaccessible records appear in missingIds without failing records that were found.
When includeProvenance is true, each company also has a provenance map parallel to values. Observation provenance can include provider, source, sourceId, capturedOn, resolution, and compact citations with id, title, type, and sourceUrl. Native and custom fallbacks identify their sourceKind. Citation excerpts and source text are not returned.
get_company
Get a full company profile by ID.
Scope: read:companies
enrichedValues with citations. Field keys match the metal://fields/companies resource.
search_company_taxonomy
Search the organization’s canonical industry → sector → subsector hierarchy by a classification term. Returns matching nodes with their IDs, names, and ancestors. Use this before list_companies or search_companies when a request describes a market, vertical, or theme without naming a company, then pass the selected industryId, sectorId, or subsectorId downstream.
Scope: read:companies
Custom fields
get_custom_field_definitions
List org-defined custom field definitions for companies and deals. Use this before passing customFilters to search_companies, list_companies, or search_deals, and before requesting organization-defined fields with get_companies.
Scope: read:companies for company fields; read:deals for deal fields.
Each definition includes the field key, display name, type, whether it can be used in
customFilters, and supported operators. String fields support eq, neq, in, and nin; number fields support eq, neq, gt, gte, lt, lte, in, and nin; boolean fields support eq and neq; date fields support range operators gt, gte, lt, and lte.
Documents
search_documents
Search document content or list documents by type and date.
Scope: read:documents
Content search — find text inside documents:
rankProfile: "bm25" to match exact terms, names, or phrases. Start with the default hybrid ranking. Retry once with bm25 if hybrid results miss the evidence you need.
sourceLinkMarkdown from each excerpt when presenting facts.
get_document
Get extracted text from a document by line number.
Scope: read:documents
reachedEof is false, call again with startLine set to nextLine.
Document deal associations
get_document, list_documents, and search_documents return a deals array on each document that is linked to one or more deals. Each entry has an id, a name, and an optional projectName. Documents with no deal association omit the deals key.
- Deal IDs require
read:documents.nameandprojectNamecome from deal data and requireread:deals.nameis always present and is empty when the connection lacksread:dealsor the name could not be resolved.projectNameis omitted when it is empty, so a connection withoutread:dealsseesidand an emptynameonly. - In
search_documentsresults,dealsUnavailable: truemeans the page’s record data couldn’t be hydrated completely, which isn’t the same as a failed deal-name lookup. A missingdealskey on that page doesn’t mean the document has no deal.
deals rather than company to attribute a document to a deal.
Other document tools
All three require
read:documents.
get_document_page
Render one physical page of a PDF document as an image. Use it when extracted text from get_document or search_documents loses chart values, layout, units, or table relationships. The tool returns the page image itself, not OCR text or a download link.
Scope: read:documents
When the renderer reports a retry delay, the message appends
Retry after <delay>.
People
search_people
Search contacts by name, title, company, or email.
Scope: read:people
list_person_tags
List person tags so you can pass exact IDs to the tagIds filter on search_people.
Scope: read:people
Returns a paginated list of tag objects with
id, type, and value, plus color and externalReference when set. Match the label against value and pass the tag’s id to tagIds.
get_person
Get a full contact profile by ID.
Scope: read:people
get_person_context
Get the aggregated context for a person: their activities and notes.
Scope: read:people and read:activities
Deals
search_deals
Search or filter deals. query is optional for filter-only searches.
Scope: read:deals
Resolve company names with
search_companies, user names with search_users, and team IDs with list_teams before passing ID filters.
get_deal
Get a full deal record by ID.
Scope: read:deals
get_deal_status_and_stages
Return the organization’s configured deal statuses and stages as customer-facing labels, plus each label’s internal enum mapping. No arguments. Call this before filtering deals by status or stage, and before update_deal_status_and_stage, so you pass a valid configured label rather than guessing.
Scope: read:deals
update_deal_status_and_stage
Move an existing deal to a different pipeline stage and/or status by deal ID. At least one of stage or status is required; values can be the org’s configured labels or Metal’s internal enums. If only one is supplied, the backend keeps the other when the pair stays consistent and otherwise fills a compatible default; an inconsistent pair (for example, a passed status with a non-passed stage) is rejected. Returns the updated deal. This is the only direct deal write tool; there is no MCP create-deal or arbitrary field editor.
Scope: read:deals and write:deals
Investor relations
Read-only tools for your firm’s limited partners (LPs), funds, and fundraising processes. A fundraising process is one LP’s participation in one fund’s raise. Each record type has its own scope:read:limited_partners, read:funds, and read:fundraising_processes.
For all three search tools, query is optional. Omit it for filter-only searches instead of passing "*". Date range filters take RFC3339 timestamps. Results use offset pagination (page, pageSize, hasMore).
search_limited_partners
Search your firm’s own LP records by name or location text. These are Metal records, not third-party data.
Scope: read:limited_partners
get_limited_partner
Get a full LP record by ID, including investor type, location, linked company, contacts, AUM, preferred check size, strategy and geography preferences, tags, notes, next steps, and custom fields.
Scope: read:limited_partners
list_limited_partner_tags
List LP tags so you can pass exact IDs to the tagIds filter on search_limited_partners.
Scope: read:limited_partners
Returns a paginated list of tag objects with
id, type, and value, plus color and externalReference when set. Match the label against value and pass the tag’s id to tagIds.
search_funds
Search the funds your firm is raising or managing by name or strategy text.
Scope: read:funds
get_fund
Get a fund by ID, including strategy, vintage, currency, target size, status, first and final close dates, owners, tags, and custom fields.
Scope: read:funds
list_fund_tags
List fund tags so you can pass exact IDs to the tagIds filter on search_funds.
Scope: read:funds
Returns a paginated list of tag objects with
id, type, and value, plus color and externalReference when set. Match the label against value and pass the tag’s id to tagIds.
search_fundraising_processes
Search fundraising processes. Each result carries its status, stage, target, soft-circled, and committed amounts, probability, expected close date, owners, source, and next steps.
Scope: read:fundraising_processes
A configured label matches only processes that carry that label. An uppercase enum matches every label mapped to it, plus processes created before labels were configured.
For time-in-stage questions, set
stageChangedBefore. To find processes in one fund that have sat in their current stage for more than 30 days, set stageChangedBefore to the timestamp 30 days before the current time and sort by stage order:
get_fundraising_process
Get a fundraising process by ID. The record includes fund and LP IDs, status and stage with their configured labels (externalStatus, externalStage), and amounts. It also includes probability, close dates, data room status, owners, notes, tags, and custom fields. Private processes you can’t access return an error.
Scope: read:fundraising_processes
get_fundraising_status_and_stages
Return your organization’s configured fundraising statuses and stages, with a mapping from each label to its internal enum value. Call it before filtering search_fundraising_processes by status or stage.
Scope: read:fundraising_processes
Takes no parameters. Active labels come first. archivedStatusLabels and archivedStageLabels list retired labels that still appear on historical processes. Labels that map to more than one internal value appear under ambiguousStatusLabels and ambiguousStageLabels instead of the mapping.
list_fundraising_process_tags
List fundraising process tags so you can pass exact IDs to the tagIds filter on search_fundraising_processes.
Scope: read:fundraising_processes
Returns a paginated list of tag objects with
id, type, and value, plus color and externalReference when set. Match the label against value and pass the tag’s id to tagIds.
Users and teams
get_current_user
Return the authenticated user and connected organization. No arguments.
Scope: read:users
search_users
Search Metal users by name or email. query is required.
Scope: read:users
get_user
Get a user by ID.
Scope: read:users
list_teams
List teams in your organization. Returns team names and IDs for use in deal and company filters.
Scope: read:teams
get_team
Get a team by ID.
Scope: read:teams
Lists
list_lists
List resource lists in your organization.
Scope: read:lists
get_list
Get a list’s metadata and column schema by ID. Does not include row data — use get_list_entries.
The response includes relationshipColumnIds, the IDs of the list’s relationship columns. Only these columns accept { "sourceId": ... } cell values.
Scope: read:lists
get_list_entries
Page through list rows with cursor pagination.
Scope: read:lists
List authoring
The list write tools let an assistant build and maintain resource lists from a chat surface — create a list, evolve its columns, add rows, and edit cells. Every write requires bothread:lists and write:lists, so tokens without the read scope cannot write either.
create_list
Create a new resource list. The list is created private to you regardless of your role; sharing is managed in the Metal UI.
Scope: read:lists and write:lists
update_list_columns, add_list_entries, and update_list_entry.
update_list
Rename a list or change its description. Only provided fields are patched.
Scope: read:lists and write:lists
At least one of
name or description is required. Use update_list_columns to change the column schema.
update_list_columns
Modify a list’s column schema by adding, removing, or renaming columns.
Scope: read:lists and write:lists
At least one of
add, remove, or rename is required. Column IDs come from get_list.
Renames run before adds and removes, so a rename that targets a missing column fails before any destructive delete commits. Removing and renaming the same column ID in a single call is rejected up front.
add_list_entries
Append rows to a list in one batch (backend cap: 1,000 entries per call).
Scope: read:lists and write:lists
Each entry supports:
resourceId and resourceType are provided together to link an entry to an existing Metal record, or both omitted for a standalone row (required for resourceType=none lists). dataEntity lists always require a resource.
failed array in the response. Each failed item includes the input index and error message. Do not assume every entry landed.
To set a relationship column, pass { "sourceId": "<resource ID>" } as the cell value.
update_list_entry
Update cell values on one existing list entry.
Scope: read:lists and write:lists
To set a relationship column, pass
{ "sourceId": "<resource ID>" } as the cell value. On Items lists, pass { "sourceId": "" } to clear it.
Relationship columns
A relationship column links each row to another Metal record and shows that record’s name. You can add relationship columns to Items lists (resourceType: "none") and to typed lists.
- Items lists: pick the linked record for each row. Use them to track rows that relate to several Metal resources, such as a row per meeting with a person column and a deal column.
- Typed lists: Metal fills the link automatically from each row’s record, including existing rows. For example, a deal list can show each deal’s company.
type: "string" and foreignResourceType to create_list or the add array of update_list_columns. Metal configures the column’s name mapping automatically. Valid foreignResourceType values match the targets the list UI offers:
Other list types don’t support relationship columns. An invalid target returns an error that lists the valid targets for the list type.
add_list_entries or update_list_entry, resolve the resource ID with the matching search tool, such as search_companies, search_people, or search_deals. Then pass { "sourceId": "<resource ID>" } as the value for a column listed in get_list’s relationshipColumnIds. sourceId must be the only key and must be a valid Metal ID. Don’t pass a name. If no matching resource exists, omit the cell.
- Items lists: pass
{ "sourceId": "" }to clear the cell. - Typed lists: omit the cell to keep the link that fills from the row’s record. Pass a
sourceIdto override that link for one row. Metal rejects{ "sourceId": "" }on typed lists, because the link would refill from the record.
update_list_entry response can still show the previous values. Read them with get_list_entries. Relationship cells never write back to the row’s source record.
Activities
get_activities
Get meetings, calls, and interactions for a company.
Scope: read:activities
get_activity
Get a single activity by ID, including participants, linked deals, and attached documents.
Scope: read:activities
update_activity
Add or remove an activity’s participants and related resources. Each change is a delta. Adds keep the entries the activity already holds, and removes unlink only the entries you name. The tool has no replace option, so a call cannot drop links that another process added. It returns the updated activity.
Scope: read:activities and write:activities
A participant email resolves to a colleague (user) first, then to an existing person. On an add, an email that matches no one creates a person, named from
displayName. On a remove, an email that matches no participant is refused. Metal reads each added related resource to check your access. Metal also checks that each added company or limited_partner participant exists in your organization. Removes match on ID and type without reading the record, so you can unlink a deleted record.
Activities created from mailbox ingestion refuse these edits. Mailbox ingestion maintains their participants and linked records, and the next sync would revert a manual change.
You cannot pass addParticipants and removeParticipants in the same call. The same applies to addRelatedResources and removeRelatedResources. To add some participants and remove others, make two calls. Each list holds at most 50 entries.
Tasks
Task tools let an assistant find, read, update, and delete Metal tasks. Reads requireread:tasks. update_task and delete_task require both read:tasks and write:tasks. The Metal API enforces task access on every call, so a caller without access to a task receives an error.
Task-returning tools use this shape. delete_task does not; it returns { "deletedTaskId": "..." }.
assigneeIds, which can hold more than one user. search_tasks filters with assigneeIds. update_task accepts assigneeIds or assigneeId. ownerIds lists the task’s access owners, not every user the task is shared with. Shared users and teams appear in sharedWith. When a task was created from another record, such as a session or workflow run, the result includes createdFrom.
Task statuses are open, in_progress, in_review, blocked, completed, and canceled. Use in_review when work is done and waiting for review, and blocked when work cannot move forward. open, in_progress, in_review, and blocked count as outstanding. Task origins are user, crm, and agent.
Every task returns an integer priority: 0 (No priority), 1 (Low), 2 (Medium), 3 (High), or 4 (Urgent). 0 is a real value, not a missing one. list_tasks and search_tasks filter with priorities, and update_task sets it with priority. Values outside 0–4 are rejected.
list_tasks
Browse tasks with structured filters only. Use it to filter by status, priority, due window, one related record, or the record a task was created from. list_tasks does not match title or description text and cannot filter by assignee or owner. Use search_tasks for those. Results page without totalCount or totalPages.
Scope: read:tasks
The server rejects an inverted due window.
dueAfter must be earlier than or equal to dueBefore, otherwise the call returns dueAfter must be earlier than or equal to dueBefore. Passing only one half of a type and ID pair also returns an error. A priorities value outside 0–4 returns priorities must be integers between 0 and 4.
search_tasks
Search tasks by text and structured filters, including people. Use it when you need to match words in a task’s title or description, or filter by assignee or owner. Results include pagination.totalCount and pagination.totalPages.
Scope: read:tasks
Resolve user IDs with
search_users, or pass "me". Blank entries in assigneeIds or ownerIds return an error.
get_task
Get one task by ID. Returns the same fields as list_tasks and search_tasks.
Scope: read:tasks
update_task
Patch an existing task. Only the fields you pass are written. Resolve the task ID with list_tasks or search_tasks, and read current values with get_task first. The tool returns the updated task. A call that changes no field returns nothing to update: pass at least one field to change.
Scope: read:tasks and write:tasks
Each replace argument is mutually exclusive with its add and remove variants.
addRelatedResources and removeRelatedResources cannot be passed in the same call. Assignees remain owners of the task. How a task was created (origin and createdFrom) cannot be changed.
Prefer the add and remove variants for sharing, owners, and tags. The replacing arguments drop any entries you did not read first.
delete_task
Permanently delete one task by ID. Deletion cannot be undone.
Scope: read:tasks and write:tasks
Skills
Skill tools let an assistant read and edit your organization’s skill library from any MCP client. Use them to run a Metal skill from Claude, Cursor, or another client, or to author a skill there without exporting and importing a.skill bundle. Metal stays the source of truth. A copy in your client is a cache.
Skills are identified by their organization-unique name. No tool takes a skill ID.
The tools apply the same rules as the Metal app. You can read the skills Metal shows you, and only a skill’s owners or an admin can edit it.
Visibility
Every skill has one of three visibility states. Thevisibility field in responses reports it.
Setting
isOrgWide: true requires the admin role.
list_skills
List the skills you can access as compact summaries. Summaries never include a skill body or companion file contents. Call get_skill for those.
Scope: read:skills
Each summary includes
id, name, description, visibility, isOwner, owners, sharedWith, assets metadata, frontmatter fields, and timestamps. Descriptions longer than 200 characters are cut and marked with descriptionTruncated: true. Page on pagination.hasMore, because totalCount can be omitted.
get_skill
Fetch one skill in full.
Scope: read:skills
The response includes
content (the SKILL.md body), description, version, frontmatter fields such as argumentHint and allowedTools, visibility and ownership fields, companionFiles metadata (name, path, contentType, size), and assets. Save version. Every write tool requires it.
Binary assets are read-only. Each asset carries a presigned downloadUrl. When Metal can’t sign a link, the asset has unavailable: true instead. A skill body over 96,000 characters is refused rather than truncated.
get_skill_file
Read the text of one companion file.
Scope: read:skills
Returns
skillName, name, path, contentType, content, size, and truncated. Content is capped at 1 MiB. A longer file returns a prefix with truncated: true. Paths that start with / or contain a .. segment are rejected.
Edit skills
The write tools requirewrite:skills. Grant read:skills with it, because every edit starts with get_skill.
Writes use the version from get_skill as an optimistic lock. Pass it as expectedVersion. If someone else saved the skill after you read it, Metal rejects the write as stale and the error includes the current version. The write doesn’t land. Call get_skill again, reapply your change, and retry with the new version.
If a create would exceed your organization’s skill quota, the tool returns an error saying the quota is full. Retrying the same save can’t succeed. Delete an existing skill in Metal, or ask an admin to raise the limit.
You can’t delete a skill or upload, replace, or remove a binary asset over MCP. Do those in the Metal app.
save_skill
Create a skill, or update one. A save writes the whole skill: on update, send the current description and content, not only the field you changed. Companion files are untouched. Use add_skill_file and remove_skill_file for those.
Scope: write:skills
A new skill is private to you unless you set visibility. On update, omitting both visibility flags leaves visibility unchanged. Setting only one flag derives the other, so a lone
isPrivate: false turns an org-wide skill into a shared one. Send both flags when you change visibility.
Creating a skill whose name already exists fails. Read the existing skill and retry the save with its version.
id, name, the new version, visibility, isPrivate, isOrgWide, created, updatedAt, and companionFiles metadata.
add_skill_file
Add a UTF-8 text companion file to a skill, or replace the file at that path.
Scope: write:skills
Returns
skillName, path, contentType, size, replaced, the new version, and totalCompanionBytes. All companion files together are limited to 1 MiB. Paths that start with / or contain a .. segment are rejected.
remove_skill_file
Remove one companion file from a skill.
Scope: write:skills
Returns
skillName, path, removed, the new version, and totalCompanionBytes. Removing a path that isn’t stored returns an error.
Screenings and scoring
search_screenings
List or filter CIM screenings. Free-text query is not supported — use structured filters.
Scope: read:screenings
get_screening
Get a screening by ID, including financials, analysis, and validation metadata.
Scope: read:screenings
get_screening_scores
Get score records for a screening.
Scope: read:screenings and read:scores
list_scoring_frameworks
List scoring frameworks visible to your organization.
Scope: read:scores
get_current_scores
Read the stored current scoring results for one company or deal. The tool doesn’t recalculate or publish scores. Large responses omit reasoning, citations, and provenance when needed to fit the response limit.
Scope: read:scores plus read:companies (for companyId) or read:deals (for dealId)
Provide exactly one of
companyId or dealId.
get_score_history
Read one page of stored scoring history for one company or deal, including invalidated events. Use it to see how a score changed over time.
Scope: read:scores plus read:companies (for companyId) or read:deals (for dealId)
Provide exactly one of
companyId or dealId. If a page exceeds the response limit, retry with the same nextToken and a smaller pageSize.
get_scoring_framework
Get a framework definition by ID. Standard frameworks use IDs like standard:Porter's Five Forces.
Scope: read:scores
Scoring families and scores
For a walkthrough connecting these tools to workflow outputs and decisions, see Add scoring to a workflow. Scoring family tools manage org-defined scoring rules used by workflows. Listing and reading requireread:workflows; create, rename, and append require read:workflows and write:workflows.
Score tools read stored scoring results and handle workflow-generated scores.
Score reads require
read:scores plus the target resource’s read scope (read:companies or read:deals). Pending score tools require read:workflows; publishing or dismissing also requires write:workflow_runs, and publishing checks the target read scope: read:companies with a company id, or read:deals with a deal id.
Dashboards
Dashboard authoring tools let an assistant build canvas dashboards end to end: create the dashboard, add widgets with agent, script, or resource-list backing, rearrange the layout, and edit widget authoring source in place. Only canvas dashboards are supported; other dashboard contexts returnno access.
Dashboard read tools use read:dashboards:
refresh_dashboard_widget busts one widget’s cache and re-resolves it; it requires both read:dashboards and write:dashboards.
Every write requires both read:dashboards and write:dashboards. Layout writes use optimistic concurrency: each write echoes the baseVersion from the caller’s most recent read, and a stale token returns 409 Conflict without persisting. On 409, re-fetch the dashboard and retry with the fresh version.
create_dashboard
Create an empty canvas dashboard. Org-scoped and private to you until shared in the UI.
Scope: read:dashboards and write:dashboards
Returns the new
dashboardId. Add widgets with add_dashboard_widget.
update_dashboard
Rename or re-describe a canvas dashboard. Sparse patch — omitted fields are unchanged; an empty string clears a field. Layout is never touched by this tool.
Scope: read:dashboards and write:dashboards
add_dashboard_widget
Add one widget to a canvas dashboard.
Scope: read:dashboards and write:dashboards
Data source rules:
agent— supplyprompt. The widget renders through Metal’s agent runtime.script— supplyscript(PythonDASHBOARD_DATA). Rejected if empty or whitespace-only; enforced against a per-script byte cap. Not allowed onLISTwidgets.resourceList— supplyresourceListId. Only valid forLISTwidgets;LISTwidgets require this data source.
list_sdk_methods and get_sdk_method to look up SDK signatures before writing widget scripts.
update_dashboard_widget
Sparse patch for one widget. Omitted fields are unchanged. widgetType cannot be changed — remove and re-add.
Scope: read:dashboards and write:dashboards
Read the current script or template with
get_dashboard_widget_source before rewriting.
reorder_dashboard_widgets
Reposition existing widgets. Widgets not listed keep their current geometry.
Scope: read:dashboards and write:dashboards
remove_dashboard_widget
Remove one widget from a canvas dashboard.
Scope: read:dashboards and write:dashboards
Removing a default or system widget is durable — the server records a tombstone so the widget is not reinserted on the next dashboard reconcile.
get_dashboard_widget_source
Read the current authoring source of a widget on a canvas dashboard: the Python script (with sha256 and byte count) for script-backed widgets, or the stored HTML template (widgetCode) for agent-backed HTML widgets. Use this before editing so you push a change against the exact source the server holds.
Scope: read:dashboards and write:dashboards (source is an authoring asset and is gated by edit access to the dashboard, not view access)
widgetCode is empty until an agent-backed HTML widget has rendered its first template.
SDK methods
The Metal SDK method catalog lets scripts discover the read-only Python methods available torun_metal_sdk_query and to dashboard widget DASHBOARD_DATA scripts. Look up methods before writing code so signatures and response shapes are confirmed rather than guessed.
Both tools are on the core MCP surface and accept either scope:
Scope: read:programmatic or read:dashboards
list_sdk_methods
Search available SDK methods by name, HTTP path, or documentation text.
get_sdk_method
Get the exact signature, route, response contract, examples, and usage notes for one method returned by list_sdk_methods.
Call
get_sdk_method before using an SDK call in a script — its examples pin down the shape you need to return from a widget’s DASHBOARD_DATA output.
Workflows
Workflow tools split into read/inspect, run, and authoring groups.Read and inspect
Scope:read:workflows
view shortcuts for get_workflow_run: overview, steps, outputs, errors, failures, artifacts, citations, full. Do not pass view and fieldPath together.
view shortcuts for get_workflow_run_step: overview, outputs, transcript, toolCalls, artifacts, errors, iteratorItems, hitl, execution, full.
Run workflows
Scope:write:workflow_runs
run_workflow
Start a workflow run. Inspect inputSchema with get_workflow first and supply every required field in input.
get_workflow_run when the run completes to read bounded outputs.
review_workflow_hitl_step
Approve or reject a human-in-the-loop step. Inspect the pending step with get_workflow_run_step using view: "hitl" first.
cancel_workflow_run
Stop an active workflow run. The tool uses the same cancellation path and permissions as cancelling a run in the Metal app. Use it when a run was started with the wrong inputs or is no longer needed. It requires both read:workflows and write:workflow_runs.
CANCELED, plus the same feedback details as run_workflow. If the run has already reached a terminal status, the call fails with a conflict error such as workflow run is already in terminal state: COMPLETED.
rerun_workflow_run_from_step
Start a new run from a chosen step of a finished run, reusing the source run’s input and seeding outputs from every step before the target. The source run must be in a terminal status, and every step before the target must have completed. The rerun uses the workflow’s current definition, so step IDs may have changed if the workflow was edited since the source run.
Authoring
Scope:write:workflows
These tools create and edit workflows:
Call
list_workflow_building_options before authoring to discover allowed step types, field shapes, and scoring families. Authoring tool inputs are validated server-side; validation errors return structured JSON in the error text.
update_workflow_details
Update a workflow’s details. Use outcomeConfig to define the outcome codes a workflow’s terminal step can report when a run completes.
Each entry in
outcomeConfig.codes has these fields:
A workflow can have 1–254 codes. Invalid input returns a validation error.
Connected MCP servers
Use these tools to reach data in remote MCP servers you connected in Metal, such as a Databricks index or SQL warehouse. Your AI client calls them through the Metal connector, using your own connection to each server. Use them when the data you need lives in one of those systems rather than in Metal’s companies, deals, and documents. To connect a server in Metal, see External MCP servers. Scope:read:connected_mcp
list_connected_mcp_tools
List your remote MCP server connections in Metal and each connection’s tools. Each tool includes its name, description, and a readOnly flag. Connections to Metal’s own MCP servers are hidden.
Call it with
server before calling one of that server’s tools, so you have the tool’s inputSchema. A connection that needs reconnecting is listed with connected: false, no tools, and an error asking you to reconnect it in Metal.
servers is empty and message tells you to connect one in Metal under Settings → Connections.
call_connected_mcp_tool
Call a read-only tool on one of your connected servers as the signed-in user, and return the tool’s result.
connectionId instead.
Resources
Your client can read MCP resources alongside tools. These are read-only catalogs — not tool calls.Prompts
The server also exposes guided prompts your client can invoke:
Prompts orchestrate multiple tool calls — they do not return data directly.
Tool index
All tools (alphabetical)
All tools (alphabetical)
add_dashboard_widget · add_list_entries · add_skill_file · add_workflow_step · append_scoring_family_rules · call_connected_mcp_tool · cancel_workflow_run · configure_workflow_input · configure_workflow_output · configure_workflow_scoring · configure_workflow_trigger · create_dashboard · create_list · create_scoring_family · create_workflow · delete_task · delete_workflow_step · dismiss_pending_workflow_score · get_activities · get_activity · get_companies · get_company · get_current_scores · get_current_user · get_custom_field_definitions · get_dashboard · get_dashboard_widget · get_dashboard_widget_source · get_deal · get_deal_status_and_stages · get_document · get_document_page · get_document_types · get_fund · get_fundraising_process · get_fundraising_status_and_stages · get_limited_partner · get_list · get_list_entries · get_person · get_person_context · get_score_history · get_scoring_family · get_scoring_framework · get_screening · get_screening_scores · get_sdk_method · get_skill · get_skill_file · get_task · get_team · get_user · get_workflow · get_workflow_run · get_workflow_run_step · get_workflow_step · list_companies · list_company_tags · list_connected_mcp_tools · list_dashboards · list_documents · list_fund_tags · list_fundraising_process_tags · list_limited_partner_tags · list_lists · list_pending_workflow_scores · list_person_tags · list_scoring_families · list_scoring_frameworks · list_sdk_methods · list_skills · list_tasks · list_teams · list_workflow_building_options · list_workflow_runs · list_workflows · move_workflow_step · propose_scoring_family · publish_pending_workflow_score · refresh_dashboard_widget · remove_dashboard_widget · remove_skill_file · rename_scoring_family · reorder_dashboard_widgets · rerun_workflow_run_from_step · review_workflow_hitl_step · run_workflow · save_skill · search_companies · search_company_taxonomy · search_deals · search_documents · search_fundraising_processes · search_funds · search_limited_partners · search_people · search_screenings · search_tasks · search_users · update_activity · update_dashboard · update_dashboard_widget · update_deal_status_and_stage · update_list · update_list_columns · update_list_entry · update_task · update_workflow_details · update_workflow_steprun_metal_sdk_query when the read:programmatic scope is granted.
