Connic can publish the existing Invoice Processor template as an MCP tool. A client sends invoice text, the agent extracts fields and checks the arithmetic with Python tools, and the connection returns the result. The setup uses the template's existing agent files and a managed MCP Server connection.
Start with the agent the template already provides
The Invoice Processor template in Connic Awesome Agents includes three agents. invoice-extractor reads invoice text and returns fields such as vendor, currency, line items, and total. It uses Python calculator tools and an invoice output schema. invoice-validator checks the extracted arithmetic deterministically. invoice-pipeline runs both in sequence and returns the validator's final summary.
This walkthrough publishes invoice-extractor so the caller receives the extracted invoice fields. Connic hosts the MCP endpoint and maps the tool call to the deployed agent. The Python code below is a client used to inspect and call that endpoint. The MCP server and client explainer covers the protocol roles in more detail.
Deploy the invoice template
Use Python 3.10 or later in an activated virtual environment. Create a Connic project without a connected Git repository for this CLI deployment. The project needs credit for agent execution as well as the template's model calls. Run the following commands from a directory where
invoice-mcpdoes not already exist.connic loginopens the Connic dashboard in the browser. Create a project API key there, copy the displayed login token, and paste it into the terminal prompt. The token contains the project ID and API key. If the browser does not open, follow the URL printed by the CLI.terminalpip install connic-composer-sdk connic init invoice-mcp --templates=invoice cd invoice-mcp pip install -r requirements.txt connic login connic deployOpen the deployment URL printed by the CLI and wait for the deployment to succeed and become active. Command completion means the deployment was submitted. With the default settings, Connic runs the included tests before activation. If a build or test fails, inspect the deployment logs before proceeding. The quickstart covers both CLI and Git deployment; projects with Git connected use their configured deployment branch.
Link the extractor to an MCP Server connection
Open
invoice-extractorin the environment with the active deployment. In its connection diagram, choose Add inbound connector, then Create New Connector and MCP Server. Select Sync (Wait for Result), keep authentication enabled, and create the connection. Link only the extractor for this example.Copy the endpoint URL and secret from the connection details. Use the complete generated URL, including its connection ID. This secret authenticates calls to this connection; the project login token from step 1 is a separate credential. The endpoint accepts an
Authorization: Bearerheader orX-Connic-Secret. Configuration details are in the MCP Server documentation.A native or server-side MCP client must support remote HTTP connections and a custom authentication header to use this endpoint. The connection uses a shared secret and provides no OAuth sign-in flow. Browser requests carrying an
Originheader are rejected. The terminal client below exercises the connection directly.Discover invoice_extractor from Python
Save the following code as
mcp_invoice.py. It uses Python's standard library and the2026-07-28protocol supported by Connic. Each request includes protocol metadata and matching HTTP headers. This diagnostic script reads the JSON responses Connic returns for these methods in that revision; a general MCP client must also handle other response forms. The Streamable HTTP specification defines the transport requirements.mcp_invoice.pyimport json import os from urllib.error import HTTPError from urllib.request import Request, urlopen endpoint = os.environ["MCP_ENDPOINT"] secret = os.environ["MCP_SECRET"] protocol_version = "2026-07-28" def request(method, params, request_id): params = { **params, "_meta": { "io.modelcontextprotocol/protocolVersion": protocol_version, "io.modelcontextprotocol/clientInfo": { "name": "invoice-tutorial", "version": "1.0.0", }, "io.modelcontextprotocol/clientCapabilities": {}, }, } headers = { "Authorization": f"Bearer {secret}", "Content-Type": "application/json", "Accept": "application/json, text/event-stream", "MCP-Protocol-Version": protocol_version, "Mcp-Method": method, } if method == "tools/call": headers["Mcp-Name"] = params["name"] body = {"jsonrpc": "2.0", "id": request_id, "method": method, "params": params} http_request = Request(endpoint, json.dumps(body).encode(), headers) try: with urlopen(http_request, timeout=310) as response: data = json.load(response) except HTTPError as error: raise RuntimeError( f"HTTP {error.code}: {error.read().decode()}" ) from error if "error" in data: raise RuntimeError(data["error"]) result = data["result"] if result.get("isError"): raise RuntimeError(result["content"]) return result tools = request("tools/list", {}, 1)["tools"] tool = next(tool for tool in tools if tool["name"] == "invoice_extractor") print(json.dumps(tool, indent=2))The MCP tool methods separate discovery from execution:
tools/listdescribes the available tools;tools/callinvokes one. Connic converts the agent nameinvoice-extractortoinvoice_extractor. The printed tool definition contains aninputSchemawith a required stringmessageand an optional objectpayload.This tool schema describes the request sent to the agent. The template's invoice schema controls the agent's output inside Connic; the MCP connection does not advertise it as an MCP
outputSchemaor return astructuredContentfield.Call the tool with a sample invoice
Append this code to the same file. It sends a fictional invoice as
payload.text. Connic merges the payload fields into the agent input, so the extractor receivesmessageandtextat the top level.mcp_invoice.py (continued)invoice_text = ( "Example Supplier, invoice INV-001. " "Issued 2026-09-11, due 2026-09-25. " "Consulting: 2 hours at EUR 100, line total EUR 200. " "Subtotal EUR 200. Tax 19%: EUR 38. Total EUR 238." ) result = request("tools/call", { "name": "invoice_extractor", "arguments": { "message": "Extract the invoice fields and check the arithmetic.", "payload": {"text": invoice_text}, }, }, 2) invoice = json.loads(result["content"][0]["text"]) print(json.dumps(invoice, indent=2)) expected = {"currency": "EUR", "subtotal": 200, "tax_amount": 38, "total": 238} for field, value in expected.items(): if invoice.get(field) != value: raise ValueError(f"Unexpected {field}: {invoice.get(field)!r}")Replace both placeholders with the connection details from step 2 and run the file in a shell that supports
export. Keep the secret in the local environment; exclude it from source files and shared transcripts.terminalexport MCP_ENDPOINT='<endpoint-url>' export MCP_SECRET='<connection-secret>' python mcp_invoice.pySync returns after the agent finishes, with up to five minutes of waiting at the connection. The extractor's own 45-second timeout still applies. The helper checks HTTP errors, JSON-RPC errors, and
result.isErrorbefore returning content. For a successful extraction,result.content[0].textcontains the invoice JSON as a string, which the second code block decodes.Check the extracted fields and inspect the run
The sample has a known calculation: two hours at EUR 100 produce a EUR 200 subtotal; 19% tax adds EUR 38, for a EUR 238 total. The script checks those numeric fields and the currency. Also compare the printed vendor, invoice number, dates, and line items with the input. The expected values come from the sample's arithmetic. A model performs the extraction, so check its output even when the tool call succeeds.
Open the agent run in the dashboard to inspect the received input, calculator calls, output, and any errors. The runs and traces guide explains the view. If the sample fails, the failing layer narrows the next check:
- An HTTP 401 points to the connection secret or authentication header.
- A missing tool or
StopIterationmeans the tool list did not containinvoice_extractor. Check the endpoint, linked agent, and agent name. - A protocol error calls for checking the protocol version, method headers, and request metadata together.
isError: truereports failed execution or a timeout. Inspect the returned error and the agent trace.- A JSON decoding error or an unexpected invoice field requires inspecting the returned text and extractor output.
Use the pipeline when the caller needs a validation summary
Link invoice-pipeline to publish a second tool named invoice_pipeline. That sequence extracts fields and then runs the deterministic validator. Its final result is the validation summary, so adapt the client parsing and checks to that result. The validator reports arithmetic discrepancies; it does not verify that a supplier or invoice is genuine.
Keep Sync when the caller needs the result in the same request. Inbound mode returns a run ID while the agent works in the background. For an application that submits invoice text over ordinary HTTP, the invoice webhook walkthrough uses the same extractor through an HTTP connection.
Link your agent to an MCP Server connection so MCP clients can call it as a tool.
Set up the MCP connection