Skip to content

MCP Server

Tendios exposes an MCP (Model Context Protocol) server so AI assistants and agents can query public procurement data and your own pipeline directly, without you writing any HTTP integration code.

MCP is an open standard for connecting language models to external tools. Once the Tendios server is connected, your assistant can search tenders, pull a tender's full details, resolve CPV codes, look up contracting authorities, read your alerts and opportunity pipeline, and — with your confirmation — create alerts, move opportunities between stages, and add tasks, all as a natural part of the conversation.

The server wraps the same v1 use cases as the REST API, returns the same versioned response contracts, and is authenticated with the same API keys.

Endpoint

https://mcp.tendios.com/api/mcp

The server speaks the Streamable HTTP transport. It runs in stateless mode — a fresh server instance is built per request, so there are no sessions to manage and no session affinity required.

PropertyValue
Server nametendios-mcp
Server version1.0.0
TransportStreamable HTTP
Tools exposed20

Requirements

MCP access requires an API key with the MCP capability enabled. This is a per-key flag, separate from the key itself: an existing REST API key will not work against the MCP server until the flag is turned on.

  1. Have an API key. If your plan includes API access you can generate one yourself — see Authentication. API access is available on Enterprise plans.
  2. Ask us to enable MCP on that key by contacting support@tendios.com. The flag is set by the Tendios team and can't be turned on from the app.

A key without the flag is rejected with 403 Forbidden:

json
{
  "statusCode": 403,
  "message": "API key is not enabled for MCP access"
}

Authentication

Authenticate exactly as you do for the REST API: send your key in the api-key header on every request. There is no OAuth flow and no token exchange.

api-key: tend_your_api_key_here

Account-scoped tools (context, alerts, pipelines, kanban, opportunities, and tasks) resolve your account from the API key itself. You never pass an account id — a key can only ever reach the data belonging to its own account. Call whoami to see which account, organization, and plan a key resolves to.

Connecting a client

Most MCP clients — Claude Code, Claude Desktop, and others — use the same mcpServers configuration shape. Add the Tendios server with your API key as a header:

json
{
  "mcpServers": {
    "tendios": {
      "type": "http",
      "url": "https://mcp.tendios.com/api/mcp",
      "headers": {
        "api-key": "tend_your_api_key_here"
      }
    }
  }
}

In Claude Code this goes in your project's .mcp.json (or add it with claude mcp add). In Claude Desktop it goes in your claude_desktop_config.json. Restart the client after editing the file, then confirm the tendios server is listed as connected.

Treat the config file as a secret

Your API key sits in plain text in these config files. Don't commit them to a public repository. If a key leaks, you can disable or delete it yourself and generate a new one, or contact support@tendios.com to have it rotated.

Verifying the connection

To check the endpoint outside a client, post a JSON-RPC request directly. MCP clients perform the initialize handshake for you; because the server is stateless you can also call methods without carrying a session id:

bash
curl -X POST https://mcp.tendios.com/api/mcp \
  -H "api-key: tend_your_api_key_here" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{ "jsonrpc": "2.0", "id": 1, "method": "tools/list" }'

A healthy server responds with the list of available tools and their input schemas.

Available tools

Twenty tools are exposed: six read public procurement data, ten read data scoped to your own account, and four write to it.

ToolScopePurpose
search_tendersPublicFull-text and faceted search over tenders
get_tenderPublicFull details of one tender by id
get_tender_sheetsPublicDocuments attached to a tender
get_cpvPublicDetails of a CPV code
get_organizationPublicOrganization profile by id or slug
get_organization_award_statsPublicAward statistics by year for an organization
whoamiAccountWhich account, organization, and plan the key resolves to
list_alertsAccountEvery alert configured for the account
get_alertAccountFull configuration of one alert
get_alert_resultsAccountTenders matching one of your saved alerts
list_pipelinesAccountPipelines and their stages, with the IDs other tools need
get_kanban_status_totalsAccountOpportunity totals per pipeline status
get_kanban_opportunities_by_statusAccountPaginated opportunities in one pipeline status
search_kanban_opportunitiesAccountSearch a pipeline, grouped by status
get_opportunity_workflow_actionsAccountWorkflow action records for an opportunity
list_opportunity_tasksAccountTasks attached to an opportunity
create_alertAccount writeCreate a new alert
update_alertAccount writeChange fields on an existing alert
change_opportunity_statusAccount writeMove an opportunity to another pipeline stage
create_opportunity_taskAccount writeAdd a task to an opportunity

See MCP Tools for the full parameter reference for each tool.

Start with list_pipelines and whoami

The kanban and opportunity tools need pipeline and stage identifiers. Rather than making you look them up, list_pipelines returns every pipeline with its stages, and the kanban tools accept either a UUID or the exact pipeline or stage name it returned. whoami confirms which account a key is acting on. Together they let an assistant orient itself in two calls before touching anything.

Response format

Every tool returns its payload as JSON inside a single text content block:

json
{
  "content": [{ "type": "text", "text": "{\"id\":\"507f1f77bcf86cd799439011\", ... }" }]
}

The JSON inside text follows the same v1 response contracts as the REST API, so a field means the same thing whether you reached it through MCP or through GET /v1/tenders/{id}. Paginated tools return the familiar { data, pagination } envelope described in Pagination.

References

Most tools also return a structuredContent.references object alongside the text. Each reference is a { type, id, label } triple naming an entity the assistant can feed straight into a follow-up tool call, so it never has to parse IDs back out of prose:

json
{
  "references": {
    "alerts": [
      { "type": "alert", "id": "507f1f77bcf86cd799439011", "label": "IT services in Madrid" }
    ]
  }
}

Reference types are tender, alert, organization, pipeline, pipeline-status, opportunity, and task.

Tools that take an entity as input are correspondingly forgiving: the alert and opportunity parameters accept a reference ID or a Tendios URL pasted from the browser, and pipeline and stage parameters accept a UUID or the exact name from list_pipelines.

Rate limits

The MCP server is rate-limited per API key, not per IP. Each key uses its own configured limit; keys without an explicit limit fall back to 30 requests per minute.

http
HTTP/1.1 429 Too Many Requests

This limit is lower than the REST API's

The REST API allows 300 requests per minute. The MCP default is 30 per minute, because a single assistant turn typically makes only a handful of tool calls. If your agent workload needs more, contact support@tendios.com to raise the limit on your key.

Exceeding the limit blocks further requests for the remainder of the 60-second window.

Errors

Authentication and authorization failures use standard HTTP status codes; tool-level failures come back as MCP error results.

CodeMeaning
401Missing api-key header, invalid key, expired or disabled key
403Valid key, but MCP access is not enabled on it
429Rate limit exceeded for this key

See Errors for the shared error body shape.

Writing data

The MCP server is no longer read-only. Four tools write to your account:

ToolWritesGuard
create_alertCreates an alertRequires confirmed: true
update_alertChanges fields on an existing alertIdempotent; omitted fields stay as they are
change_opportunity_statusMoves an opportunity to another stageRequires confirmTerminal: true for terminal stages
create_opportunity_taskAdds a task to an opportunityRequires confirmed: true

Nothing deletes. There is no tool that removes an alert, opportunity, or task — the most destructive action available is moving an opportunity into a terminal stage, which closes it.

Two-step confirmation

create_alert and create_opportunity_task refuse to act on the first call. Invoked without confirmed: true, they return an error result instructing the assistant to summarize what it is about to create and ask you to approve it; only a second call carrying confirmed: true performs the write. change_opportunity_status works the same way for terminal stages via confirmTerminal, and short-circuits harmlessly when the opportunity is already in the requested stage.

This puts the approval step inside the protocol rather than relying on the client to ask. Clients that surface MCP tool annotations will also show these four as non-read-only, with change_opportunity_status flagged destructive.

A key with MCP enabled can modify your account

Because writes share the same credential as reads, any key with the MCP flag can create alerts and tasks and move opportunities. If you want an assistant that can only look, don't hand it a key with MCP enabled — use the REST API read endpoints instead.

Not available as tools

  • Tender sheet file download — binary streams don't map onto MCP tool results. Use get_tender_sheets, which returns short-lived Tendios download links, and fetch the file over HTTP.
  • API key lifecycle metadatawhoami deliberately exposes only safe caller context (principal, account, organization, plan). Key prefixes, expiry, and rate limits are not reachable from MCP; use GET /v1/api-key for those.

© Tendios