Before you start
You need:- A Govly account with a paid seat. Enterprise API access is not required to connect.
- A client that supports remote HTTP MCP servers.
- A Govly API key if your client only accepts a static bearer token — either a personal key or an agent account key, depending on who is driving the connection.
Choose an authentication method
Start with one question: is this connection an integration, or is it you?
The deciding question for that last row: if the person who set this up left tomorrow, should it keep running? If yes, use an agent account. A personal key stops working when that person is deactivated, which takes the integration down with them.
Connect with OAuth
1
Add a remote MCP server
In your client, add a remote MCP server named
Govly with the URL https://app.govly.com/api/mcp.2
Sign in to Govly
Follow the browser prompt and sign in to your existing Govly account. Govly’s OAuth flow does not create new users.
3
Approve access
Review the authorization request and approve the connection.
4
Test the connection
Ask the client to list its Govly tools or try a small request such as, “What workspaces do I have in Govly?”
Connect with a personal API key
Create a personal API key
1
Open API settings
In Govly, go to Settings → API → API Keys.
2
Create a personal key
Under Personal API Keys, select New key and name it after the client that will use it.
3
Copy and store the key
Copy the
gk_... token into a secret manager or environment variable. The token stays visible on this page, so treat access to your API settings as access to the key itself.Configure your client
Most MCP clients accept a configuration block like this:Connect through an AI provider API
When an AI provider API supports remote MCP servers:- Add a remote MCP server named
govly. - Use
https://app.govly.com/api/mcpas the server URL. - Use your personal Govly API key as the server authorization token.
- Require approval for tool calls while you test the integration.
- Start with a low-risk request, such as listing Govly tools or running one opportunity search.
Verify the connection
Send a JSON-RPCtools/list request with your personal key:
search_opportunities, search_awards, search_contacts, search_places, list_places, document_read, document_download, search_workspaces, list_workspaces, list_organization_users, attach_file. Use search_workspaces to discover the organization’s Active Work; use list_workspaces when you already know an exact associated entity type and ID. Use list_organization_users for your organization’s member roster with emails and roles; list_user_opp_activity reports engagement counts rather than the roster.
To manage your organization’s labels, use list_organization_labels, create_organization_label, update_organization_label, and delete_organization_label. Any member can list labels; creating, updating, and deleting them requires an organization admin on a paid plan.
To label records, use add_record_labels and remove_record_labels on an opportunity, award, contact, or workspace you can view. Any member can label records. show_opportunity, show_award, show_contact, and show_workspace include your organization’s labels on the record.
Link to created records
Workspace responses includedata.url. Comment creation returns data.workspaceUrl. Upload completion returns data.targetUrl and the original data.target; both supported target types open the containing workspace. Use these returned URLs in descriptive Markdown links when reporting results to users. workspaceUrl opens the workspace; it is not a permalink to an individual comment or file.
Attach files to workspaces and comments
Useattach_file for an existing Govly file or a new external file. Both paths return an attachment ID and a Govly link after attachment succeeds. Supported targets are workspace and workspace_comment; comments must already exist.
This capability is being rolled out per organization. It appears in tool discovery only when enabled for your organization.
Existing Govly files
Call once with a reference to an authorized source record:fileRef from list_workspace_attachments or a prior attach_file result. Govly AI can also use the session_attachment:<id> entry IDs supplied for files in its current conversation. The server checks source access and destination permission independently and reuses the existing bytes. Source references never grant permission by themselves; raw blob IDs are not accepted.
Govly AI uploads conversation files before the agent runs. Its agent uses those existing references; it cannot perform a separate host transfer after receiving upload_required. Upload a missing file into the conversation first.
New external files
File bytes travel from the host to a signed Govly URL, outside MCP arguments. The host needs file access and HTTP execution; client support varies.- Have the host determine the exact byte size and compute the base64 MD5 digest, for example
openssl dgst -md5 -binary ./quote.pdf | openssl base64 -A. - Call
attach_filewith the target andfile: { "type": "new", "filename": "quote.pdf", "contentType": "application/pdf", "fileSize": 12345, "checksum": "<host-computed base64 MD5>" }. The sample size and digest must be replaced with actual host-computed values. Files must be 1–52,428,800 bytes (50 MiB), filenames at most 255 bytes without paths/control characters, and MIME types without parameters. Metadata validation does not inspect file format or scan content. - A result with
data.status: "upload_required"is pending: no file has been attached. Have the host POST raw bytes todata.uploadUrlusingdata.methodand exactlydata.requiredHeaders. For example, usecurl --fail --request POST --data-binary @./quote.pdfwith the returned URL and one--headerargument per returned header. The transport Content-Type is application/octet-stream; the file’s actual MIME type comes from step 2. No OAuth header, API key, AWS headers, or multipart encoding is needed. Govly returns HTTP 204 after verifying and storing the file. Accepted bytes cannot be overwritten by replaying the URL. - Call
attach_fileagain within 15 minutes, with the same target and the returned upload reference:
Results and permissions
Onlydata.status: "attached" means the file is attached. The response includes fileId, reusable fileRef, target, targetUrl, workspaceId, workspaceUrl, optional commentId, filename, MIME type, byte size, and textExtractStatus. Link to the returned targetUrl or workspaceUrl in user-facing responses. Comment links open the containing workspace. Text extraction may still be processing.
To target a comment, use { "type": "workspace_comment", "id": "456" }. Attaching preserves its body and existing files. Workspace write permission is required; comments also require edit permission. Permissions are rechecked before signing, while receiving bytes, and when attaching, including retries. Archived users and inactive workspace memberships do not grant upload access. An upload remains bound to its creating caller and original target; a comment cannot move it to another workspace.
Retry completion with the same upload reference to receive the same attachment while the token is valid. Repeating an existing-reference call for the same blob and target also returns the same attachment. Repeating new-file metadata prepares a new pending upload; use the returned upload reference to resume. Expired transfers need fresh metadata preparation. Abandoned upload blobs are scheduled for cleanup after 24 hours; attached files are retained. Cleanup depends on background-job execution and is independent of token expiration.
MCP control calls use the existing OAuth connection or personal API key. REST integrations use POST /api/tools/v1/file_attachments with the same JSON contract and existing personal-key/Enterprise API authentication. The signed byte request uses only its temporary URL. The multipart endpoint, POST /api/tools/v1/workspaces/{workspaceId}/attachments, also remains available.
Multipart uploads require the same workspace write permission as attach_file; an archived user or explicitly inactive workspace membership cannot authorize an upload. The rollout gate applies to the new attachment operation and signed byte endpoint, while the existing multipart endpoint remains available.
Connect with an agent account key
An agent account is a non-human identity in your organization. It holds its own API keys, so a durable integration does not depend on an employee’s account and does not share an organization-wide credential that belongs to nobody. Agent accounts are not people. They have no mailbox, cannot sign in, do not receive notifications or digests, and cannot be shared with or @-mentioned. They act only through their API keys.1
Create the agent
An organization admin goes to Settings → API → Agent Accounts and creates an agent, naming it after the integration it will run.
2
Create a key
Select New key on that agent, then copy the
gk_... token.3
Store the key
Put it in a secret manager or environment variable, never in source control. The token stays visible on the Agent Accounts page, so anyone who can administer your organization’s API settings can read it. Revoke a key if you suspect it has been exposed — revocation is immediate and permanent.
4
Connect your client
Use the same configuration as a personal key, with the agent’s token as the bearer value.
Agent accounts cannot use OAuth, because they cannot sign in. That also means they cannot be used with the Govly connector in the hosted Claude app, which authorizes through a browser sign-in. Use an agent key from a client that accepts a bearer token — a command-line tool, an AI provider API, or your own scheduled job.
Developing against an agent account
Use the agent’s key while you build the integration, not your own. You will be testing with the identity that will actually run in production, so permission and subscription differences surface during development rather than after deploy.Deciding what to build on
MCP is worth its complexity when a model needs to choose which tools to call. If your code already knows which calls to make — fetch new matches, filter by NAICS, write to your CRM — the Tools API is simpler, cheaper, and easier to test. An agent account key works on either surface.Multiple Govly organizations
OAuth connections, personal API keys, and agent accounts are all scoped to the Govly organization where they were authorized or created. To connect another organization, authorize a separate OAuth connection while viewing that organization, or create a separate key from it.Manage keys
Key-based connections do not appear under Connected Apps.- Personal keys — Govly Settings → API → API Keys.
- Agent account keys — Govly Settings → API → Agent Accounts, on the agent that owns them.
Workflow reference files
Workflow file tools and access require theworkflow-monitors rollout, which defaults off. Uploads
also require file-attachments. Disabling workflow-monitors hides the tools and blocks new file access.
Use list_workflows with an optional search to discover workflow IDs. Use attach_file with
target: {type: "workflow", id: "WORKFLOW_ID"} and the existing new/upload/reference file contract.
The response includes workflowId, targetUrl, and fileRef: "workflow_attachment:ID".
Workflow references are valid sources for subsequent attach_file calls too.
list_workflow_attachments(workflowId: "...") returns current files and their extraction status.
Pass documentType: "workflow_attachment" and the returned id to document_read or document_download.
Both lists accept perPage (default 25, maximum 100) and cursor; follow meta.nextCursor until absent.
Organization members can read; organization admins can add files and use
delete_workflow_attachment(workflowId: "...", attachmentId: "...") to remove them.
Uploads require the file-attachments rollout. Removal prevents new reads but cannot remove text already
read into a conversation. Workflow files are reference context; attaching them does not add them to emails.
REST clients can list workflows with GET /api/tools/v1/workflows, list or upload files at
/api/tools/v1/workflows/{workflowId}/attachments, and remove a file with DELETE on its nested ID route.
Workflow file preview/download URLs are temporary storage URLs. Use document_download to refresh an expired link. Revoking access or removing a workflow file blocks new tool reads; previously issued storage URLs remain usable until expiry.
Troubleshooting
Still stuck? Email support@govly.com with the client you’re using and any error messages you’re seeing.