Skip to main content
Glama
AWfusion

portal-api

by AWfusion
README.md
# Portal.io API MCP

A local, read-only MCP server for a Portal.io account. It signs API requests with Portal's HMAC-SHA256 scheme and makes account data available to Codex through structured tools.

## Included tools

- `test_connection`: confirm the current credentials can make a read-only request.
- `list_proposals` and `get_proposal`: browse proposal summaries and details.
- `list_users`: look up Portal salesperson IDs.
- `search_contacts`: find contacts in the Portal account.
- `search_catalog`: search account catalog items when Catalog API access is enabled.

Version `0.1.1` contains no mutation tools. It cannot create, update, archive, or send anything in Portal.

## Install

```sh
git clone https://github.com/AWfusion/portal-api-mcp.git
cd portal-api-mcp
npm ci
cp .env.example .env
```

Fill in `.env` with credentials from the same Portal environment:

```env
PORTAL_ENV=sandbox
PORTAL_BASE_URL=https://sandbox.api.portal.io
PORTAL_APP_ID=your-api-application-key
PORTAL_SECRET_KEY=your-secret-key
PORTAL_USER_API_KEY=the-meta-apiKey-value-from-the-credential-exchange
PORTAL_WRITE_ENABLED=false
```

For production, use `PORTAL_ENV=production` and `PORTAL_BASE_URL=https://api.portal.io` only when Portal has issued and enabled production credentials for the integration.

`PORTAL_USER_API_KEY` must be the exact `meta.apiKey` returned by `GET /authenticate/apikeyexchange`. Do not substitute the application ID, secret key, a Portal UI token, or the username/password used for the one-time exchange. Portal's returned User API Key is Base64-encoded and is normally 44 characters long.

The actual `.env` file is ignored by Git. Keep its permissions owner-only:

```sh
chmod 600 .env
```

## Verify

```sh
npm test
npm run verify
```

`npm run verify` performs a local MCP initialization, confirms every tool is registered, and makes one read-only `GET /public/proposals?PageNumber=1&PageSize=1` call. It outputs no credentials.

## Register Globally in Codex

Run the included installer from the project directory:

```sh
./scripts/install-codex-mcp.sh
```

It registers this local process globally under the name `portal-api`. Confirm it with:

```sh
codex mcp get portal-api
```

Restart Codex or open a new task after registration so the tools are discovered. Typical requests include “list my most recently modified Portal proposals” and “search the catalog for Denon receivers.”

## Troubleshooting

- `app id could not be found`: the API application ID is not enabled for the selected base URL. Sandbox credentials belong at `https://sandbox.api.portal.io`; production credentials belong at `https://api.portal.io`.
- `request signature (hash) is invalid`: first confirm `PORTAL_USER_API_KEY` is the Base64 `meta.apiKey` returned by the credential exchange, then confirm the app ID, secret, and User API Key all came from the same environment.
- Catalog queries return authorization errors: ask Portal to enable Catalog API access for the account.

## Development

The server uses Node 20 or newer and has no database or hosted component. Request signing follows Portal's current API contract: GET signatures include the fully encoded request URL and omit the content type; the API secret is used as the raw ASCII HMAC key and is not Base64-decoded.

See [CHANGELOG.md](CHANGELOG.md) for release history and [BUILD-INFO.md](BUILD-INFO.md) for the release contract.

TDQS

A3.8/5.0

Scored across 6 tools

Disambiguation5/5

Each tool targets a distinct resource and action: proposals (get/list), users (list), catalog (search), contacts (search), and connection test. No overlap.

Naming Consistency5/5

All tool names follow a consistent verb_noun pattern in snake_case (e.g., get_proposal, list_users, search_catalog).

Tool Count5/5

6 tools is appropriate for a read-only API surface covering proposals, users, catalog, contacts, and connection verification.

Completeness4/5

Covers the main read operations for key entities, but lacks get_user or get_contact individually; however, this is reasonable for the scope.

Maintenance

ActivitySlowing
ResponsivenessNo issues